Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
9
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Open sidebar
Christian
reddmeet-chrome-extension
Commits
a0528e49
Commit
a0528e49
authored
Feb 22, 2016
by
Christian
Browse files
works mostly, sans fade-out-in
parent
84e44157
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
376 additions
and
97 deletions
+376
-97
content.js
content.js
+112
-33
manifest.json
manifest.json
+8
-0
popup.html
popup.html
+61
-2
popup.js
popup.js
+195
-62
No files found.
content.js
View file @
a0528e49
(
function
()
{
chrome
.
runtime
.
onMessage
.
addListener
(
function
(
msg
,
sender
,
sendResponse
)
{
console
.
log
(
'
--> content.js: chrome.runtime.onMessage.addListener
'
);
console
.
log
(
'
--> content.js: msg.text:
'
+
msg
.
text
);
//var baseUserURL = 'http://redddate.com/u/';
var
baseUserURL
=
'
http://localhost:8000/u/
'
;
if
(
msg
.
text
==
'
harvest_usernames
'
)
{
console
.
log
(
'
--> content.js: msg.text == "harvest_usernames"
'
);
sendResponse
([
'
user1
'
,
'
user2
'
,
'
user3
'
]);
//sendResponse(findRedditUsernames());
}
var
elHtml
=
document
.
getElementsByTagName
(
'
html
'
)[
0
];
var
elHead
=
document
.
getElementsByTagName
(
'
head
'
)[
0
];
var
elBody
=
document
.
getElementsByTagName
(
'
body
'
)[
0
];
var
elContent
=
elBody
.
querySelector
(
'
div.content[role="main"]
'
);
var
ico
=
'
icon.png
'
;
chrome
.
runtime
.
onMessage
.
addListener
(
function
(
msg
,
sender
,
sendResponse
)
{
//console.log('content.js: chrome.runtime.onMessage.addListener');
//console.log('content.js: msg.text: ' + msg.text);
if
(
msg
.
text
===
'
page_fadeout
'
)
{
// This fades only a virgin page, so its possible to open
// and close the popup repeatedly, without re-rendering
// the page every time.
var
loadingGif
=
chrome
.
extension
.
getURL
(
"
/loading.gif
"
);
if
(
!
isPageDone
())
{
elBody
.
style
.
opacity
=
'
0
'
;
elBody
.
style
.
transition
=
'
0.15s
'
;
elHtml
.
style
.
background
=
'
#FFF url(
'
+
loadingGif
+
'
) center center no-repeat
'
;
}
sendResponse
(
true
);
}
if
(
msg
.
text
===
'
page_fadein
'
)
{
elBody
.
style
.
opacity
=
"
1
"
;
elBody
.
style
.
transition
=
"
0.75s
"
;
elHtml
.
style
.
backgroundColor
=
"
#FFF
"
;
sendResponse
(
true
);
}
if
(
msg
.
text
===
'
get_usernames
'
)
{
var
usernames
=
getUsernames
();
sendResponse
(
usernames
);
}
if
(
msg
.
text
===
'
mark_members
'
)
{
addStyle
();
markMemberUsers
(
msg
.
userlist
);
sendResponse
(
true
);
}
});
if
(
msg
.
text
==
'
mark_members
'
)
{
console
.
log
(
'
--> content.js: msg.text == "mark_members"
'
);
if
(
msg
.
userlist
)
{
console
.
log
(
'
--> content.js: msg.userlist.length ==
'
+
msg
.
userlist
.
length
);
function
getUsernames
(
)
{
// Return usernames from cache or find them in the markup.
if
(
isPageDone
()
)
{
return
getCachedUsernames
(
);
}
else
{
console
.
log
(
'
--> content.js: msg.userlist not defined
'
);
var
usernames
=
findRedditUsernames
();
cacheUsernames
(
usernames
);
return
usernames
;
}
}
markMemberUsers
(
msg
.
userlist
);
sendResponse
(
true
);
function
cacheUsernames
(
usernames
)
{
// Cache usernames in a meta tag.
elHead
.
innerHTML
+=
'
<meta name="redddate-page-done" content="
'
+
usernames
.
join
(
'
'
)
+
'
">
'
;
}
});
function
getCachedUsernames
()
{
// Return usernames from cache or null.
var
s
=
elHead
.
querySelector
(
'
meta[name="redddate-page-done"]
'
).
content
;
//console.log('content.js: getCachedUsernames(): s == ' + s);
return
(
s
)
?
s
.
split
(
'
'
)
:
null
;
}
function
findRedditUsernames
()
{
var
all
=
document
.
all
[
0
].
querySelectorAll
(
'
div.content[role="main"] p.tagline a.author
'
);
var
li
=
[];
function
isPageDone
()
{
// Checks if the page is done already.
return
!!
elHead
.
querySelector
(
'
meta[name="redddate-page-done"]
'
);
}
for
(
var
i
=
0
;
i
<
all
.
length
;
i
++
)
li
.
push
(
all
[
i
].
innerHTML
);
function
findRedditUsernames
()
{
var
all
=
document
.
all
[
0
].
querySelectorAll
(
'
div.content[role="main"] p.tagline a.author
'
);
var
li
=
[];
return
li
;
}
for
(
var
i
=
0
;
i
<
all
.
length
;
i
++
)
li
.
push
(
all
[
i
].
innerHTML
);
function
markMemberUsers
(
userlist
)
{
var
s
=
userlist
.
join
(
'
<br>
'
);
var
elHead
=
document
.
getElementsByTagName
(
'
head
'
)[
0
];
var
elContent
=
document
.
all
[
0
].
querySelector
(
'
div.content[role="main"]
'
);
var
ico
=
'
icon.png
'
//console.log('content.js: findRedditUsernames(): Found ' + li.length + ' usernames.');
return
li
;
}
elHead
.
innerHTML
+=
'
<style>.reddmeet-icon { display: block; overflow: hidden; width: 1em; height: 1em; background: transparent url(chrome-extension://__MSG_@@extension_id__/icon12.png) center center no-repeat; background-size: cover; border: 0; margin: 0; padding: 0; }</style>
'
;
function
addStyle
()
{
var
s
=
''
+
'
.reddmeet-link {
'
+
'
display: inline-block; height: 24px; line-height: 24px;
'
+
'
border: 0; outline: 0;
'
+
'
margin: 0; padding: 0 4px 0 0;
'
+
'
border-radius: 10px; background-color: #F3F3F3;
'
+
'
box-shadow: 0 0 2px rgba(0,0,0,0.56);
'
+
'
}
'
+
'
.reddmeet-icon {
'
+
'
display: inline-block; width: 32px; height: 24px; border-radius: 10px 0 0 10px;
'
+
'
background: transparent url(http://redddate.com/static/icon32.png) center center no-repeat;
'
+
'
background-size: cover;
'
+
'
border: 0; border-right: 8px solid transparent;
'
+
'
outline: 0; margin: 0; padding: 0;
'
+
'
vertical-align: middle;
'
+
'
}
'
;
elContent
.
innerHTML
=
''
;
for
(
var
i
=
0
;
i
<
userlist
.
length
;
i
++
)
{
elContent
.
innerHTML
+=
'
<p><span class="reddmeet-icon"></span>
'
+
userlist
[
i
]
+
'
</p
'
;
//document.getElementsByTagName('style')[0].innerText += s;
if
(
!
document
.
getElementById
(
'
reddmeet-style
'
))
{
elHead
.
innerHTML
+=
'
<style id="reddmeet-style">
'
+
s
+
'
</style>
'
;
}
}
}
function
markMemberUsers
(
userlist
)
{
for
(
var
i
=
0
;
i
<
userlist
.
length
;
i
++
)
{
// loop through all the userlist objects.
var
qs
=
'
a.author[href="https://www.reddit.com/user/
'
+
userlist
[
i
][
'
name
'
]
+
'
"]
'
;
var
qr
=
elContent
.
querySelectorAll
(
qs
);
if
(
qr
&&
qr
.
length
>
0
)
{
// was there at least one element for this username?
for
(
var
j
=
0
;
j
<
qr
.
length
;
j
++
)
{
// loop all the occurences of this username on the page.
if
(
!
qr
[
j
].
parentNode
.
classList
.
contains
(
'
reddmeet-link
'
))
{
// only if its not already wrapped.
qr
[
j
].
outerHTML
=
'
<span class="reddmeet-link"><a class="reddmeet-icon" href="
'
+
baseUserURL
+
userlist
[
i
][
'
name
'
]
+
'
" style="background-image:url(
'
+
userlist
[
i
][
'
pic
'
]
+
'
)"></a>
'
+
qr
[
j
].
outerHTML
+
'
</span>
'
;
}
}
}
}
}
})();
\ No newline at end of file
manifest.json
View file @
a0528e49
...
...
@@ -17,6 +17,14 @@
"permissions"
:
[
"activeTab"
,
"http://localhost:8000/"
,
"http://redddate.com/"
,
"https://reddmeet.com/"
],
"web_accessible_resources"
:
[
"loading.gif"
,
"*.css"
,
"*.js"
]
}
popup.html
View file @
a0528e49
...
...
@@ -6,17 +6,76 @@
body
{
font-family
:
"Segoe UI"
,
"Lucida Grande"
,
Tahoma
,
sans-serif
;
font-size
:
100%
;
width
:
500px
;
width
:
400px
;
min-height
:
300px
;
max-height
:
80vh
;
margin
:
0
;
padding
:
0
;
}
#status
{
white-space
:
normal
;
overflow
:
hidden
;
margin
:
0
;
padding
:
0
;
}
#status
p
{
margin
:
0
;
padding
:
4px
;
}
#loading
{
display
:
block
;
overflow
:
hidden
;
height
:
300px
;
background
:
#FFFFFF
url(loading.gif)
center
center
no-repeat
;
}
#userlist
{
list-style
:
none
;
margin
:
0
;
padding
:
0
;
}
#userlist
li
{
margin
:
0
;
padding
:
0
;
}
#userlist
li
a
{
border
:
1px
solid
transparent
;
color
:
black
;
display
:
block
;
margin
:
0
;
padding
:
8px
;
overflow
:
hidden
;
text-decoration
:
none
;
}
#userlist
li
a
:hover
{
background-color
:
#F3F3F3
;
border-color
:
gray
;
}
#userlist
li
a
span
.infoline1
{
display
:
block
;
font-size
:
20px
;
line-height
:
28px
;
overflow
:
hidden
;
}
#userlist
li
a
span
.infoline2
{
color
:
gray
;
display
:
block
;
line-height
:
20px
;
overflow
:
hidden
;
}
#userlist
li
a
img
{
border
:
0
;
outline
:
0
;
display
:
block
;
float
:
left
;
margin
:
0
8px
0
0
;
padding
:
0
;
vertical-align
:
middle
;
width
:
48px
;
height
:
48px
;
}
#userlist-empty
{
color
:
gray
;
display
:
block
;
font-size
:
1.25rem
;
margin
:
0
;
padding
:
100px
0
0
0
;
text-align
:
center
;
}
</style>
<script
src=
"popup.js"
></script>
<script
src=
"content.js"
></script>
</head>
<body>
<div
id=
"status"
></div>
<div
id=
"status"
>
<div
id=
"loading"
></div>
</div>
</body>
</html>
popup.js
View file @
a0528e49
(
function
()
{
var
currCount
=
0
;
var
currTab
=
null
;
var
currUsers
=
null
;
Object
.
prototype
.
getName
=
function
()
{
var
funcNameRegex
=
/function
(
.
{1,})\(
/
;
var
results
=
(
funcNameRegex
).
exec
((
this
).
constructor
.
toString
());
return
(
results
&&
results
.
length
>
1
)
?
results
[
1
]
:
""
;
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
function
()
{
getCurrentTabUrl
(
function
(
tab
)
{
if
(
isRedditUrl
(
tab
.
url
)
)
{
currTab
=
tab
;
// http://stackoverflow.com/a/13486540/5520354
function
unique_set
(
arr
)
{
return
arr
.
filter
(
function
(
e
,
i
,
arr
)
{
return
arr
.
lastIndexOf
(
e
)
===
i
;
});
}
if
(
currUsers
===
null
)
{
currCount
+=
1
;
renderStatus
(
'
[
'
+
currCount
+
'
]
'
);
currUsers
=
[];
// This prevents the userlist to be generated again.
chrome
.
tabs
.
sendMessage
(
currTab
.
id
,
{
text
:
'
get_all_usernames
'
},
receiveUserlist
);
}
Array
.
prototype
.
contains
=
function
(
obj
)
{
return
!
(
this
.
indexOf
(
obj
)
<
0
);
}
renderStatus
(
'
Loading...
'
);
};
});
});
///////////////////////////////////////////////////////////////////////
var
DEBUG
=
true
;
///////////////////////////////////////////////////////////////////////
//var baseUserURL = 'http://redddate.com/u/';
//var baseApiUrl = 'http://redddate.com/api/v1/';
var
baseUserURL
=
'
http://localhost:8000/u/
'
;
var
baseApiUrl
=
'
http://localhost:8000/api/v1/
'
;
function
isRedditUrl
(
url
)
{
var
re
=
new
RegExp
(
"
^https?://(
\
w+
\
.)+reddit.com(:
\
d+)?[$/]
"
);
return
url
.
match
(
re
);
}
var
isBusy
=
false
;
// only fetch one tab at a time.
var
currTab
=
null
;
// the tab we are currently working on.
function
getCurrentTabUrl
(
callback
)
{
var
queryInfo
=
{
active
:
true
,
currentWindow
:
true
,
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
function
()
{
getCurrentTabUrl
(
function
(
tab
)
{
if
(
!
isBusy
)
{
if
(
isRedditUrl
(
tab
.
url
))
{
// Only do anything if we are not already
// busy and the tab contains a Reddit URL.
isBusy
=
true
;
currTab
=
tab
;
setTimeout
(
function
(){
// wait a little for the page content to fade out.
chrome
.
tabs
.
sendMessage
(
currTab
.
id
,
{
text
:
'
get_usernames
'
},
receiveUserlist
);
},
250
);
chrome
.
tabs
.
query
(
queryInfo
,
function
(
tabs
)
{
var
tab
=
tabs
[
0
];
callback
(
tab
);
}
else
{
// not reddit
replaceStatus
(
'
Visit a reddit comment thread.
'
)
}
}
else
{
//replaceStatus();
}
});
});
}
function
receiveUserlist
(
userlist
)
{
if
(
!
userlist
)
{
renderStatus
(
'
Did NOT get userlist :(
'
);
return
;
///////////////////////////////////////////////////////////////////////
function
isRedditUrl
(
url
)
{
var
re
=
new
RegExp
(
"
^https?://(
\
w+
\
.)+reddit.com(:
\
d+)?[$/]
"
);
return
url
.
match
(
re
);
}
currUsers
=
queryReddmeetUsernames
(
unique_set
(
userlist
));
chrome
.
tabs
.
sendMessage
(
currTab
.
id
,
{
text
:
'
mark_members
'
,
'
userlist
'
:
userlist
},
function
(
response
){
//renderStatus(' !returned from mark_member_usernames! ');
});
}
function
renderStatus
(
statusText
)
{
document
.
getElementById
(
'
status
'
).
textContent
+=
'
\n
'
+
statusText
;
}
function
queryReddmeetUsernames
(
users
)
{
// For a list of usernames, query the reddmeet API if they have an account.
// The API returns a list of usernames that do have a reddmeet profile.
// ::: TODO :::
return
users
;
}
///////////////////////////////////////////////////////////////////////
Object
.
prototype
.
getName
=
function
()
{
var
funcNameRegex
=
/function
(
.
{1,})\(
/
;
var
results
=
(
funcNameRegex
).
exec
((
this
).
constructor
.
toString
());
return
(
results
&&
results
.
length
>
1
)
?
results
[
1
]
:
""
;
};
// http://stackoverflow.com/a/13486540/5520354
function
unique_set
(
arr
)
{
return
arr
.
filter
(
function
(
e
,
i
,
arr
)
{
return
arr
.
lastIndexOf
(
e
)
===
i
;
});
}
function
getCurrentTabUrl
(
callback
)
{
var
queryInfo
=
{
active
:
true
,
currentWindow
:
true
,
};
chrome
.
tabs
.
query
(
queryInfo
,
function
(
tabs
)
{
var
tab
=
tabs
[
0
];
callback
(
tab
);
});
}
function
receiveUserlist
(
userlist
)
{
if
(
typeof
userlist
==
'
undefined
'
)
{
replaceStatus
(
'
popup.js: Uhm, userlist is undefined. Do nothing.
'
);
}
else
if
(
userlist
===
null
)
{
//replaceStatus('popup.js: Already done userlist, do not fetch it again.');
}
else
if
(
userlist
.
length
===
0
)
{
//replaceStatus('popup.js: Got empty userlist, do nothing.');
}
else
{
userlist
=
unique_set
(
userlist
);
// remove duplicates.
if
(
userlist
.
length
===
0
)
{
//replaceStatus('popup.js: Got empty userlist, do nothing.');
}
else
{
// with the list of usernames, check which have a reddmeet account
// and pass the resulting list on to the markMembers function.
queryReddmeetUsernames
(
userlist
).
then
(
markMembers
);
}
}
}
function
markMembers
(
userlist
)
{
// receives a list of usernames that are members of reddmeet.
// mark them in the page's HTML and render them as a list in
// the popup bubble.
//
// userlist = [{ 'name': 'username', 'pic': 'http://...' }, { ... }, ]
var
html
=
''
;
if
(
userlist
.
length
>
0
)
{
for
(
var
i
=
0
;
i
<
userlist
.
length
;
i
++
)
{
var
pic
=
'
<img src="
'
+
userlist
[
i
][
'
pic
'
]
+
'
" alt="">
'
;
var
ahref
=
'
<a href="
'
+
baseUserURL
+
userlist
[
i
][
'
name
'
]
+
'
">
'
;
var
infoLine1
=
'
<span class="infoline1">
'
+
userlist
[
i
][
'
name
'
]
+
'
</span>
'
;
var
infoLine2
=
'
<span class="infoline2">33, woman who like men</span>
'
;
html
+=
'
<li>
'
+
ahref
+
pic
+
infoLine1
+
infoLine2
+
'
</a></li>
'
;
}
replaceStatus
(
'
<ul id="userlist">
'
+
html
+
'
</ul>
'
);
chrome
.
tabs
.
sendMessage
(
currTab
.
id
,
{
text
:
'
page_fadeout
'
},
function
(
response
){
});
chrome
.
tabs
.
sendMessage
(
currTab
.
id
,
{
text
:
'
mark_members
'
,
'
userlist
'
:
userlist
},
function
(
response
){
});
chrome
.
tabs
.
sendMessage
(
currTab
.
id
,
{
text
:
'
page_fadein
'
},
function
(
response
){
});
isBusy
=
false
;
}
else
{
replaceStatus
(
'
<p id="userlist-empty">there is nobody</p>
'
);
isBusy
=
false
;
}
}
function
clearStatus
()
{
document
.
getElementById
(
'
status
'
).
innerHTML
=
''
;
}
function
addStatus
(
statusText
)
{
document
.
getElementById
(
'
status
'
).
innerHTML
+=
'
<p>
'
+
statusText
+
'
</p>
'
;
}
function
replaceStatus
(
statusText
)
{
document
.
getElementById
(
'
status
'
).
innerHTML
=
statusText
;
}
function
queryReddmeetUsernames
(
userlist
)
{
// For a list of usernames, query the reddmeet API if they have an account.
// The API returns a list of usernames that do have a reddmeet profile.
// ::: TODO :::
return
new
Promise
(
function
(
resolve
,
reject
)
{
// Try to fetch users from sessionStorage.
var
cache
=
JSON
.
parse
(
sessionStorage
.
getItem
(
'
reddmeetUsers
'
));
var
userlistComplete
=
[];
// collect here all items wuth full data from cache.
var
usernamesTodo
=
[];
// collect here all items that are sent to reddmeet server.
for
(
var
j
=
0
;
j
<
userlist
.
length
;
j
++
)
{
var
isCached
=
false
;
if
(
cache
&&
cache
.
length
>
0
){
for
(
var
i
=
0
;
i
<
cache
.
length
;
i
++
)
{
if
(
cache
[
i
][
'
name
'
]
==
userlist
[
j
])
{
userlistComplete
.
push
(
cache
[
i
]);
// Found one!
isCached
=
true
;
break
;
}
}
}
if
(
!
isCached
)
{
usernamesTodo
.
push
(
userlist
[
j
]);
// add to "sent to server" list
}
}
if
(
usernamesTodo
.
length
==
0
)
{
resolve
(
userlistComplete
);
// nothing to send to server?
}
// Only get fresh data for those users not found in sessionStorage.
var
apiUrl
=
baseApiUrl
+
'
filter-members.json?userlist=
'
+
encodeURIComponent
(
usernamesTodo
.
join
(
'
'
));
var
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
"
GET
"
,
apiUrl
,
true
);
xhr
.
onreadystatechange
=
function
()
{
if
(
xhr
.
readyState
==
xhr
.
DONE
)
{
if
(
xhr
.
status
==
200
)
{
var
data
=
JSON
.
parse
(
xhr
.
responseText
);
// TODO: add this userlist to cache, avoiding dupes.
var
userlist
=
data
[
'
userlist
'
].
concat
(
userlistComplete
);
// join the resulting userlist with the userlist from cache
resolve
(
userlist
);
}
else
if
(
xhr
.
status
==
404
)
{
resolve
(
mockUserlist
(
usernamesTodo
));
}
}
}
xhr
.
send
();
});
}
function
mockUserlist
(
usernames
)
{
// Return a fake list of user objects with pics if DEBUG, else an empty list.
var
response
=
[];
var
fakepics
=
[
'
https://i.imgur.com/JuJwWLCs.jpg
'
,
'
https://i.imgur.com/WgfwLfIs.jpg
'
,
'
https://i.imgur.com/P02Ejbfs.jpg
'
,
'
https://i.imgur.com/50z3fWPs.jpg
'
,
'
https://i.imgur.com/TSmS03Ds.jpg
'
,
'
https://i.imgur.com/CJQmX50s.jpg
'
];
if
(
DEBUG
)
{
for
(
var
i
=
0
;
i
<
usernames
.
length
;
i
++
)
{
var
p
=
Math
.
floor
(
i
%
fakepics
.
length
);
response
.
push
({
'
name
'
:
usernames
[
i
],
'
pic
'
:
fakepics
[
p
]
});
}
}
return
response
;
}
})();
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment