Merge branch 'mayhem' into v3 (Bugtesting time... yey... ;__;)

Conflicts:
	css/burichan.css
	css/futaba.css
	css/photon.css
	css/tomorrow.css
	css/yotsuba-b.css
	css/yotsuba.css
	html/General/Settings-section-Main.html
	html/General/Settings.html
	src/Filtering/PostHiding.coffee
	src/General/Build.coffee
	src/General/Get.coffee
	src/General/Header.coffee
	src/General/Index.coffee
	src/General/Settings.coffee
	src/Miscellaneous/AnnouncementHiding.coffee
	src/Monitoring/ThreadUpdater.coffee
This commit is contained in:
Zixaphir 2014-02-28 19:59:04 -07:00
commit db5cccc70f
28 changed files with 259 additions and 1298 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<button class="export">Export Settings</button>
<button class="import">Import Settings</button>
<button class="reset">Reset Settings</button>
<input type="file" hidden>

View File

@ -0,0 +1,15 @@
<div id="fourchanx-settings" class="dialog">
<nav>
<div class="sections-list"></div>
<div class="credits">
<a href="<%= meta.page %>" target="_blank"><%= meta.name %></a>
&nbsp;|&nbsp;
<a href="<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md" target="_blank">#{g.VERSION}</a>
&nbsp;|&nbsp;
<a href="<%= meta.repo %>blob/<%= meta.mainBranch %>/CONTRIBUTING.md#reporting-bugs-and-suggestions" target="_blank">Issues</a>
&nbsp;|&nbsp;
<a href="javascript:;" class="close fa fa-times" title="Close"></a>
</div>
</nav>
<section></section>
</div>

View File

@ -5,8 +5,8 @@
"http": true,
"https": true,
"software": "foolfuuka",
"boards": ["a", "biz", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
"files": ["a", "biz", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"]
"boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
"files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"]
}, {
"uid": 1,
"name": "NSFW Foolz",
@ -52,15 +52,6 @@
"software": "foolfuuka",
"boards": ["d", "i"],
"files": ["d", "i"]
}, {
"uid": 7,
"name": "Install Gentoo",
"domain": "archive.installgentoo.net",
"http": false,
"https": true,
"software": "fuuka",
"boards": ["diy", "g", "sci"],
"files": []
}, {
"uid": 8,
"name": "Rebecca Black Tech",
@ -86,8 +77,8 @@
"http": false,
"https": true,
"software": "fuuka",
"boards": ["3", "biz", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"],
"files": ["3", "biz", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"]
"boards": ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"],
"files": ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"]
}, {
"uid": 15,
"name": "fgts",
@ -123,6 +114,6 @@
"https": true,
"withCredentials": true,
"software": "foolfuuka",
"boards": ["a", "biz", "co", "d", "gd", "jp", "m", "mlp", "s4s", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
"files": ["a", "biz", "d", "gd", "jp", "m", "s4s", "tg", "u", "vg", "vp", "vr", "wsg"]
"boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "mlp", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
"files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"]
}]

View File

@ -36,7 +36,7 @@
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-shell": "~0.6.4",
"load-grunt-tasks": "~0.3.0"
"load-grunt-tasks": "~0.4.0"
},
"repository": {
"type": "git",

View File

@ -2,12 +2,10 @@ PostHiding =
init: ->
@db = new DataBoard 'hiddenPosts'
@hideButton = $.el 'a',
className: 'hide-post-button'
innerHTML: '<i class="fa fa-minus-square-o"></i>'
className: 'hide-post-button fa fa-minus-square-o'
href: 'javascript:;'
@showButton = $.el 'a',
className: 'show-post-button'
innerHTML: '<i class="fa fa-plus-square-o"></i>'
className: 'show-post-button fa fa-plus-square-o'
href: 'javascript:;'
Post.callbacks.push
@ -61,13 +59,14 @@ PostHiding =
PostHiding.saveHiddenState post
return if post.isReply
if Conf['JSON Navigation']
Index.updateHideLabel()
Index.sort()
Index.buildIndex()
else
# XXX Tempfix until I feel like writing out real functionality for thread hiding without JSON functions
$.rm post.nodes.root.parentElement
Index.updateHideLabel()
if Conf['Index Mode'] is 'all pages' or !Conf['JSON Navigation'] # ssllooooww
root = post.nodes.root.parentNode
$.rm root.nextElementSibling
$.rm root
return
Index.sort()
Index.buildIndex()
saveHiddenState: (post, val) ->
data =

View File

@ -121,11 +121,11 @@ Build =
if file?.isDeleted
fileHTML = if isOP
"<div class=file id=f#{postID}><span class=fileThumb>" +
"<div class=file><span class=fileThumb>" +
"<img src='#{staticPath}filedeleted#{gifIcon}' class=fileDeleted>" +
"</span></div>"
else
"<div class=file id=f#{postID}><span class=fileThumb>" +
"<div class=file><span class=fileThumb>" +
"<img src='#{staticPath}filedeleted-res#{gifIcon}' class=fileDeletedRes>" +
"</span></div>"
else if file
@ -159,7 +159,7 @@ Build =
filename = a.innerHTML.replace /'/g, '&apos;'
fileDims = if file.name[-3..] is 'pdf' then 'PDF' else "#{file.width}x#{file.height}"
fileInfo = "<div class=fileText id=fT#{postID}#{if file.isSpoiler then " title='#{filename}'" else ''}>File: <a href='#{file.url}' target=_blank>#{file.timestamp}</a>" +
fileInfo = "<div class=fileText#{if file.isSpoiler then " title='#{filename}'" else ''}>File: <a href='#{file.url}' target=_blank>#{file.timestamp}</a>" +
"-(#{fileSize}, #{fileDims}#{
if file.isSpoiler
''
@ -167,7 +167,7 @@ Build =
", <span#{if filename isnt shortFilename then " title='#{filename}'" else ''}>#{shortFilename}</span>"
}" + ")</div>"
fileHTML = "<div class=file id=f#{postID}>#{fileInfo}#{imgSrc}</div>"
fileHTML = "<div class=file>#{fileInfo}#{imgSrc}</div>"
else
fileHTML = ''

View File

@ -14,14 +14,10 @@ Get =
threadFromNode: (node) ->
Get.threadFromRoot $.x 'ancestor::div[@class="thread"]', node
postFromRoot: (root) ->
link = $ 'a[title="Highlight this post"]', root
boardID = link.pathname.split('/')[1]
postID = link.hash[2..]
index = root.dataset.clone
post = g.posts["#{boardID}.#{postID}"]
if index then post.clones[index] else post
postFromNode: (root) ->
Get.postFromRoot $.x '(ancestor::div[contains(@class,"postContainer")][1]|following::div[contains(@class,"postContainer")][1])', root
post = g.posts[root.dataset.fullID]
if index = root.dataset.clone then post.clones[index] else post
postFromNode: (node) ->
Get.postFromRoot $.x 'ancestor::div[contains(@class,"postContainer")][1]', node
contextFromNode: (node) ->
Get.postFromRoot $.x 'ancestor::div[parent::div[@class="thread"]][1]', node
postDataFromLink: (link) ->

View File

@ -393,8 +393,7 @@ Header =
hashScroll: ->
hash = @location.hash[1..]
return unless /^p\d+$/.test(hash) and post = $.id hash
return if (Get.postFromRoot post).isHidden
return if (Get.postFromNode post).isHidden
Header.scrollTo post
scrollTo: (root, down, needed) ->

View File

@ -138,7 +138,6 @@ Index =
$.rm navLink for navLink in $$ '.navLinks'
$.after $.x('child::form/preceding-sibling::hr[1]'), Index.navLinks
$.rmClass doc, 'index-loading'
@cb.toggleCatalogMode()
@ -147,6 +146,7 @@ Index =
$.replace pagelist, Index.pagelist
else
$.after $.id('delform'), Index.pagelist
$.rmClass doc, 'index-loading'
scroll: $.debounce 100, ->
return if Index.req or Conf['Index Mode'] isnt 'infinite' or (doc.scrollTop <= doc.scrollHeight - (300 + window.innerHeight)) or g.VIEW is 'thread'
@ -566,12 +566,10 @@ Index =
thread.collect() unless thread.ID in Index.liveThreadIDs
buildThreads: ->
Index.nodes = []
threads = []
posts = []
threads = []
posts = []
for threadData, i in Index.liveThreadData
threadRoot = Build.thread g.BOARD, threadData
Index.nodes.push threadRoot
if thread = g.BOARD.threads[threadData.no]
thread.setPage i // Index.threadsNumPerPage
thread.setCount 'post', threadData.replies + 1, threadData.bumplimit
@ -665,7 +663,7 @@ Index =
when 'filecount'
sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.images - a.images).map (data) -> data.no
Index.sortedThreads = sortedThreadIDs
.map (threadID) -> Get.threadFromRoot Index.nodes[Index.liveThreadIDs.indexOf threadID]
.map (threadID) -> g.BOARD.threads[threadID]
.filter (thread) -> thread.isHidden is Index.showHiddenThreads
if Index.isSearching
Index.sortedThreads = Index.querySearch(Index.searchInput.value) or Index.sortedThreads

View File

@ -126,34 +126,30 @@ Settings =
$.get Conf, (Conf) ->
# XXX don't export archives.
delete Conf['archives']
Settings.downloadExport {version: g.VERSION, date: Date.now(), Conf}
downloadExport: (data) ->
Settings.downloadExport 'Settings', {version: g.VERSION, date: Date.now(), Conf}
downloadExport: (title, data) ->
a = $.el 'a',
download: "<%= meta.name %> v#{g.VERSION}-#{data.date}.json"
download: "<%= meta.name %> v#{g.VERSION} #{title}.#{data.date}.json"
href: "data:application/json;base64,#{btoa unescape encodeURIComponent JSON.stringify data, null, 2}"
<% if (type === 'userscript') { %>
p = $ '.imp-exp-result', Settings.dialog
$.rmAll p
$.add p, a
<% } %>
<% if (type === 'userscript') { %>$.add d.body, a<% } %>
a.click()
<% if (type === 'userscript') { %>$.rm a<% } %>
import: ->
$('input', @parentNode).click()
$('input[type=file]', @parentNode).click()
onImport: ->
return unless file = @files[0]
output = $('.imp-exp-result')
unless confirm 'Your current settings will be entirely overwritten, are you sure?'
output.textContent = 'Import aborted.'
return
return unless confirm 'Your current settings will be entirely overwritten, are you sure?'
reader = new FileReader()
reader.onload = (e) ->
try
Settings.loadSettings JSON.parse e.target.result
if confirm 'Import successful. Reload now?'
window.location.reload()
catch err
output.textContent = 'Import failed due to an error.'
alert 'Import failed due to an error.'
c.error err.stack
return
if confirm 'Import successful. Reload now?'
window.location.reload()
reader.readAsText file
loadSettings: (data) ->
version = data.version.split '.'
@ -231,7 +227,7 @@ Settings =
if data.Conf['WatchedThreads']
data.Conf['watchedThreads'] = boards: ThreadWatcher.convert data.Conf['WatchedThreads']
delete data.Conf['WatchedThreads']
$.set data.Conf
$.clear -> $.set data.Conf
reset: ->
if confirm 'Your current settings will be entirely wiped, are you sure?'
$.clear -> window.location.reload() if confirm 'Reset successful. Reload now?'

View File

@ -40,6 +40,12 @@
background-color: rgba(255, 255, 255, .14);
}
/* Post Hiding */
:root.burichan .hide-post-button,
:root.burichan .show-post-button {
color: #000;
}
/* QR */
.burichan #dump-list::-webkit-scrollbar-thumb {
background-color: #D6DAF0;

View File

@ -39,6 +39,11 @@
background-color: rgba(255, 255, 255, .14);
}
/* Post Hiding */
:root.futaba .hide-post-button,
:root.futaba .show-post-button {
color: #800000;
}
/* QR */
.futaba #dump-list::-webkit-scrollbar-thumb {

View File

@ -39,6 +39,12 @@
background-color: rgba(255, 255, 255, .14);
}
/* Post Hiding */
:root.photon .hide-post-button,
:root.photon .show-post-button {
color: #333 !important;
}
/* QR */
.photon #dump-list::-webkit-scrollbar-thumb {
background-color: #DDD;

View File

@ -380,7 +380,7 @@ div.center:not(.ad-cnt) {
}
#fourchanx-settings > nav a.close {
text-decoration: none;
padding: 0 2px;
padding: 2px 2px .5em;
}
.section-container {
overflow: auto;
@ -627,6 +627,10 @@ span.hide-announcement {
font-size: 13px;
font-weight: 100;
}
a.hide-announcement {
float: left;
font-size: 14px;
}
/* Unread */
#unread-line {

View File

@ -39,6 +39,12 @@
background-color: rgba(0, 0, 0, .14);
}
/* Post Hiding */
:root.tomorrow .hide-post-button,
:root.tomorrow .show-post-button {
color: #C5C8C6 !important;
}
/* QR */
.tomorrow #dump-list::-webkit-scrollbar-thumb {
background-color: #282A2E;

View File

@ -39,6 +39,12 @@
background-color: rgba(255, 255, 255, .14);
}
/* Post Hiding */
:root.yotsuba .hide-post-button,
:root.yotsuba .show-post-button {
color: #E0BFB7;
}
/* QR */
.yotsuba-b #dump-list::-webkit-scrollbar-thumb {
background-color: #D6DAF0;

View File

@ -39,6 +39,12 @@
background-color: rgba(255, 255, 255, .14);
}
/* Post Hiding */
:root.yotsuba-b .hide-post-button,
:root.yotsuba-b .show-post-button {
color: #B7C5D9;
}
/* QR */
.yotsuba #dump-list::-webkit-scrollbar-thumb {
background-color: #F0E0D6;

View File

@ -1,4 +1,4 @@
"""#{if isOP then '' else "<div class=sideArrows id=sa#{postID}>&gt;&gt;</div>"}
"""#{if isOP then '' else "<div class=sideArrows>&gt;&gt;</div>"}
<div id=p#{postID} class='post #{if isOP then 'op' else 'reply'}#{
if capcodeIcon is 'admin_highlight' then
' highlightPost'
@ -8,7 +8,7 @@
#{if isOP then fileHTML else ''}
<div class='postInfo' id=pi#{postID}>
<div class='postInfo'>
<input type=checkbox name=#{postID} value=delete>
#{' '}<span class=subject>#{subject or ''}</span>#{' '}
<span class='nameBlock#{capcodeClass}'>
@ -31,6 +31,6 @@
#{if isOP then '' else fileHTML}
<blockquote class=postMessage id=m#{postID}>#{comment or ''}</blockquote>#{' '}
<blockquote class=postMessage>#{comment or ''}</blockquote>#{' '}
</div>"""

View File

@ -303,10 +303,17 @@ do ->
$.delete = (keys) ->
if typeof keys is 'string'
keys = [keys]
local = []
sync = []
for key in keys
delete items.local[key]
delete items.sync[key]
chrome.storage.sync.remove keys
if key in $.localKeys
local.push key
delete items.local[key]
else
sync.push key
delete items.sync[key]
chrome.storage.local.remove local
chrome.storage.sync.remove sync
$.get = (key, val, cb) ->
if typeof cb is 'function'

View File

@ -6,9 +6,10 @@ class Post
@ID = +root.id[2..]
@fullID = "#{@board}.#{@ID}"
@cleanup root if that.isOriginalMarkup
post = $ '.post', root
info = $ '.postInfo', post
@cleanup root, post if that.isOriginalMarkup
root.dataset.fullID = @fullID
@nodes =
root: root
post: post
@ -149,9 +150,11 @@ class Post
if @file.isImage = /(jpg|png|gif)$/i.test @file.name
@file.dimensions = fileText.textContent.match(/\d+x\d+/)[0]
cleanup: (root) ->
cleanup: (root, post) ->
for node in $$ '.mobile', root
$.rm node
for node in $$ '[id]', post
node.removeAttribute 'id'
for node in $$ '.desktop', root
$.rmClass node, 'desktop'
return

View File

@ -35,13 +35,4 @@ Menu =
button
toggle: (e) ->
try
# Posts, inlined posts, hidden replies.
post = Get.postFromNode @
catch
post = if fullID = @parentNode.parentNode.dataset.fullID
g.threads[fullID].OP
else
# Hidden threads.
Get.threadFromNode(@).OP
Menu.menu.toggle e, @, post
Menu.menu.toggle e, @, Get.postFromNode @

View File

@ -9,7 +9,7 @@ RelativeDates =
when 'thread'
return unless Conf['Relative Post Dates']
@flush()
$.on d, 'visibilitychange ThreadUpdate', @flush if g.VIEW is 'thread'
$.on d, 'visibilitychange ThreadUpdate', @flush
else
return

View File

@ -93,10 +93,9 @@ ThreadUpdater =
Thread.callbacks.disconnect 'Thread Updater'
node: ->
ThreadUpdater.thread = @
ThreadUpdater.root = @OP.nodes.root.parentNode
ThreadUpdater.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0]
ThreadUpdater.outdateCount = 0
ThreadUpdater.thread = @
ThreadUpdater.root = @OP.nodes.root.parentNode
ThreadUpdater.lastPost = +Object.keys(@posts).sort()[-1..][0]
ThreadUpdater.cb.interval.call $.el 'input', value: Conf['Interval']

View File

@ -82,7 +82,7 @@ ThreadWatcher =
ThreadWatcher.refresh()
$.event 'CloseMenu'
toggle: ->
ThreadWatcher.toggle Get.postFromNode(@).thread
ThreadWatcher.toggle Get.threadFromNode @
rm: ->
[boardID, threadID] = @parentNode.dataset.fullID.split '.'
ThreadWatcher.rm boardID, +threadID

View File

@ -39,7 +39,7 @@ QuoteInline =
if $.hasClass @, 'inlined'
QuoteInline.rm @, boardID, threadID, postID, context
else
return if $.x "ancestor::div[@id='p#{postID}']", @
return if $.x "ancestor::div[@id='pc#{postID}']", @
QuoteInline.add @, boardID, threadID, postID, context
@classList.toggle 'inlined'