Start to get style settings built in.
This commit is contained in:
parent
8f53b3275c
commit
96b63abc6b
File diff suppressed because one or more lines are too long
@ -47,7 +47,7 @@ div.navLinks > a:first-of-type::after {
|
|||||||
/* Thread Navigation Links */
|
/* Thread Navigation Links */
|
||||||
#navlinks a {
|
#navlinks a {
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
top: 2px;
|
top: 0;
|
||||||
}
|
}
|
||||||
#navlinks a:last-of-type {
|
#navlinks a:last-of-type {
|
||||||
#{align}: #{position[i++]}px;
|
#{align}: #{position[i++]}px;
|
||||||
@ -73,7 +73,7 @@ div.navLinks > a:first-of-type::after {
|
|||||||
div.navLinks > a:first-of-type::after,
|
div.navLinks > a:first-of-type::after,
|
||||||
#catalog::after,
|
#catalog::after,
|
||||||
body > a[style="cursor: pointer; float: right;"]::after {
|
body > a[style="cursor: pointer; float: right;"]::after {
|
||||||
top: 2px !important;
|
top: 0 !important;
|
||||||
}
|
}
|
||||||
#{if _conf["Announcements"] is "slideout" then "#globalMessage," else ""}
|
#{if _conf["Announcements"] is "slideout" then "#globalMessage," else ""}
|
||||||
#{if _conf["Slideout Watcher"] then "#watcher," else ""}
|
#{if _conf["Slideout Watcher"] then "#watcher," else ""}
|
||||||
|
|||||||
@ -1403,15 +1403,15 @@ a:only-of-type > .remove {
|
|||||||
#{if _conf["Rounded Edges"] then "border-radius: 3px;" else ""}
|
#{if _conf["Rounded Edges"] then "border-radius: 3px;" else ""}
|
||||||
}
|
}
|
||||||
#appchanx-settings h3,
|
#appchanx-settings h3,
|
||||||
.keybinds_tab,
|
.section-keybinds,
|
||||||
.mascots_tab,
|
.section-mascots,
|
||||||
.main_tab,
|
.section-main,
|
||||||
.style_tab {
|
.style {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.keybinds_tab table,
|
.section-keybinds table,
|
||||||
.main_tab ul,
|
.section-main fieldset,
|
||||||
.style_tab ul {
|
.section-style fieldset {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
#appchanx-settings ul {
|
#appchanx-settings ul {
|
||||||
@ -1431,11 +1431,11 @@ a:only-of-type > .remove {
|
|||||||
padding: 0 3px;
|
padding: 0 3px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
.sections-list label {
|
.sections-list > a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
#{if _conf["Rounded Edges"] then "border-radius: 3px 3px 0 0;" else ""}
|
#{if _conf["Rounded Edges"] then "border-radius: 3px 3px 0 0;" else ""}
|
||||||
}
|
}
|
||||||
.sections-list label {
|
.sections-list > a {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
@ -1451,18 +1451,17 @@ a:only-of-type > .remove {
|
|||||||
#appchanx-settings h3 {
|
#appchanx-settings h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.main_tab li,
|
.section-main fieldset > div,
|
||||||
.style_tab li,
|
.section-style fieldset > div,
|
||||||
.rice_tab li {
|
.section-rice fieldset > div {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
padding: 0 5px 0 7px;
|
padding: 0 5px 0 7px;
|
||||||
list-style-type: none;
|
|
||||||
}
|
}
|
||||||
#appchanx-settings tr:nth-of-type(2n+1),
|
#appchanx-settings tr:nth-of-type(2n+1),
|
||||||
.main_tab li:nth-of-type(2n+1),
|
.section-main fieldset > div:nth-of-type(2n+1),
|
||||||
.rice_tab li:nth-of-type(2n+1),
|
.section-rice fieldset > div:nth-of-type(2n+1),
|
||||||
.style_tab li:nth-of-type(2n+1),
|
.section-style fieldset > div:nth-of-type(2n+1),
|
||||||
.keybinds_tab li:nth-of-type(2n+1),
|
.section-keybinds fieldset > div:nth-of-type(2n+1),
|
||||||
#selectrice li:nth-of-type(2n+1) {
|
#selectrice li:nth-of-type(2n+1) {
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
@ -1480,19 +1479,19 @@ article li {
|
|||||||
.rice + .optionlabel {
|
.rice + .optionlabel {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
#appchanx-settings .style_tab ul,
|
#appchanx-settings .section-style fieldset,
|
||||||
#appchanx-settings .main_tab ul {
|
#appchanx-settings .section-main fieldset {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
#{if _conf["Single Column Mode"] then "margin: 0 auto 6px;" else "margin: 0 3px 6px;\n display: inline-block;"}
|
#{if _conf["Single Column Mode"] then "margin: 0 auto 6px;" else "margin: 0 3px 6px;\n display: inline-block;"}
|
||||||
}
|
}
|
||||||
.main_tab li,
|
.section-main fieldset > div,
|
||||||
.styleoption {
|
.styleoption {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
.style_tab .suboptions ul {
|
.section-style fieldset > div {
|
||||||
width: 370px;
|
width: 370px;
|
||||||
}
|
}
|
||||||
.main_tab ul {
|
.section-main fieldset {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
.suboptions,
|
.suboptions,
|
||||||
@ -1519,10 +1518,10 @@ article li {
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
.style_tab .suboptions {
|
.section-style .suboptions {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
#appchanx-settingsContent textarea {
|
.section-container textarea {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
min-height: 350px;
|
min-height: 350px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
@ -1630,7 +1629,7 @@ opacity: 0;
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
/* Themes Tab */
|
/* Themes Tab */
|
||||||
.theme_tab h1 {
|
#themes h1 {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 300px;
|
right: 300px;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
@ -1638,7 +1637,7 @@ opacity: 0;
|
|||||||
#{agent}transition: all .2s ease-in-out;
|
#{agent}transition: all .2s ease-in-out;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.theme_tab .selectedtheme h1 {
|
#themes .selectedtheme h1 {
|
||||||
right: 11px;
|
right: 11px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ html {
|
|||||||
background-attachment: #{theme["Background Attachment"] or ''};
|
background-attachment: #{theme["Background Attachment"] or ''};
|
||||||
background-position: #{theme["Background Position"] or ''};
|
background-position: #{theme["Background Position"] or ''};
|
||||||
}
|
}
|
||||||
#appchanx-settingsContent,
|
.section-container,
|
||||||
#exlinks-options-content,
|
#exlinks-options-content,
|
||||||
#mascotcontent,
|
#mascotcontent,
|
||||||
#themecontent {
|
#themecontent {
|
||||||
@ -56,7 +56,7 @@ html {
|
|||||||
border: 1px solid #{theme["Reply Border"]};
|
border: 1px solid #{theme["Reply Border"]};
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
#selected_tab {
|
.tab-selected {
|
||||||
background: #{backgroundC};
|
background: #{backgroundC};
|
||||||
border-color: #{theme["Reply Border"]};
|
border-color: #{theme["Reply Border"]};
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
|
|||||||
@ -1331,10 +1331,11 @@ MascotTools =
|
|||||||
Mascots[name] = JSON.parse(JSON.stringify(mascot))
|
Mascots[name] = JSON.parse(JSON.stringify(mascot))
|
||||||
Conf["mascot"] = name
|
Conf["mascot"] = name
|
||||||
delete Mascots[name].name
|
delete Mascots[name].name
|
||||||
userMascots = $.get "userMascots", {}
|
$.get "userMascots", {}, (item) ->
|
||||||
userMascots[name] = Mascots[name]
|
userMascots = item['userMascots']
|
||||||
$.set 'userMascots', userMascots
|
userMascots[name] = Mascots[name]
|
||||||
alert "Mascot \"#{name}\" saved."
|
$.set 'userMascots', userMascots
|
||||||
|
alert "Mascot \"#{name}\" saved."
|
||||||
|
|
||||||
close: ->
|
close: ->
|
||||||
Conf['editMode'] = false
|
Conf['editMode'] = false
|
||||||
@ -1367,9 +1368,10 @@ MascotTools =
|
|||||||
|
|
||||||
Mascots[name] = imported
|
Mascots[name] = imported
|
||||||
|
|
||||||
userMascots = $.get "userMascots", {}
|
$.get "userMascots", {}, (item) ->
|
||||||
userMascots[name] = Mascots[name]
|
userMascots = item['userMascots']
|
||||||
$.set 'userMascots', userMascots
|
userMascots[name] = Mascots[name]
|
||||||
|
$.set 'userMascots', userMascots
|
||||||
|
|
||||||
alert "Mascot \"#{name}\" imported!"
|
alert "Mascot \"#{name}\" imported!"
|
||||||
$.rm $("#mascotContainer", d.body)
|
$.rm $("#mascotContainer", d.body)
|
||||||
@ -1387,10 +1389,11 @@ ThemeTools =
|
|||||||
|
|
||||||
if Themes[key]
|
if Themes[key]
|
||||||
editTheme = JSON.parse(JSON.stringify(Themes[key]))
|
editTheme = JSON.parse(JSON.stringify(Themes[key]))
|
||||||
if ($.get "userThemes", {})[key]
|
$.get "userThemes", {}, (items) ->
|
||||||
editTheme["Theme"] = key
|
if items[key]
|
||||||
else
|
editTheme["Theme"] = key
|
||||||
editTheme["Theme"] = key += " [custom]"
|
else
|
||||||
|
editTheme["Theme"] = key += " [custom]"
|
||||||
else
|
else
|
||||||
editTheme = JSON.parse(JSON.stringify(Themes['Yotsuba B']))
|
editTheme = JSON.parse(JSON.stringify(Themes['Yotsuba B']))
|
||||||
editTheme["Theme"] = "Untitled"
|
editTheme["Theme"] = "Untitled"
|
||||||
|
|||||||
@ -29,8 +29,7 @@ Header =
|
|||||||
customBoardList = $.el 'span',
|
customBoardList = $.el 'span',
|
||||||
id: 'custom-board-list'
|
id: 'custom-board-list'
|
||||||
$.add fullBoardList, [nav.childNodes...]
|
$.add fullBoardList, [nav.childNodes...]
|
||||||
$.add nav, [customBoardList, fullBoardList, Header.shortcuts, $ '#navtopright', fullBoardList]
|
$.add nav, [customBoardList, fullBoardList, Header.shortcuts, $ '#navtopright', fullBoardList, Header.bar]
|
||||||
$.add d.body, Header.bar
|
|
||||||
|
|
||||||
if Conf['Custom Board Navigation']
|
if Conf['Custom Board Navigation']
|
||||||
Header.generateBoardList Conf['boardnav']
|
Header.generateBoardList Conf['boardnav']
|
||||||
@ -1354,7 +1353,7 @@ Keybinds =
|
|||||||
if Conf['Bottom header']
|
if Conf['Bottom header']
|
||||||
topMargin = 0
|
topMargin = 0
|
||||||
else
|
else
|
||||||
headRect = Header.toggle.getBoundingClientRect()
|
headRect = Header.bar.getBoundingClientRect()
|
||||||
topMargin = headRect.top + headRect.height
|
topMargin = headRect.top + headRect.height
|
||||||
if postEl = $ '.reply.highlight', thread
|
if postEl = $ '.reply.highlight', thread
|
||||||
$.rmClass postEl, 'highlight'
|
$.rmClass postEl, 'highlight'
|
||||||
@ -1420,7 +1419,7 @@ Nav =
|
|||||||
if Conf['Bottom header']
|
if Conf['Bottom header']
|
||||||
topMargin = 0
|
topMargin = 0
|
||||||
else
|
else
|
||||||
headRect = Header.toggle.getBoundingClientRect()
|
headRect = Header.bar.getBoundingClientRect()
|
||||||
topMargin = headRect.top + headRect.height
|
topMargin = headRect.top + headRect.height
|
||||||
threads = $$ '.thread:not([hidden])'
|
threads = $$ '.thread:not([hidden])'
|
||||||
for thread, i in threads
|
for thread, i in threads
|
||||||
|
|||||||
@ -328,15 +328,28 @@ Main =
|
|||||||
if ['b', 'd', 'e', 'gif', 'h', 'hc', 'hm', 'hr', 'pol', 'r', 'r9k', 'rs', 's', 'soc', 't', 'u', 'y'].contains g.BOARD
|
if ['b', 'd', 'e', 'gif', 'h', 'hc', 'hm', 'hr', 'pol', 'r', 'r9k', 'rs', 's', 'soc', 't', 'u', 'y'].contains g.BOARD
|
||||||
g.TYPE = 'nsfw'
|
g.TYPE = 'nsfw'
|
||||||
|
|
||||||
|
$.get "userThemes", {}, (item) ->
|
||||||
|
for name, theme of item["userThemes"]
|
||||||
|
Themes[name] = theme
|
||||||
|
|
||||||
|
$.get "userMascots", {}, (item) ->
|
||||||
|
for name, mascot of item["userMasctos"]
|
||||||
|
Mascots[name] = mascot
|
||||||
|
|
||||||
if Conf["NSFW/SFW Mascots"]
|
if Conf["NSFW/SFW Mascots"]
|
||||||
g.MASCOTSTRING = "Enabled Mascots #{g.TYPE}"
|
g.MASCOTSTRING = "Enabled Mascots #{g.TYPE}"
|
||||||
else
|
else
|
||||||
g.MASCOTSTRING = "Enabled Mascots"
|
g.MASCOTSTRING = "Enabled Mascots"
|
||||||
|
|
||||||
Conf["Enabled Mascots"] = $.get "Enabled Mascots", []
|
items =
|
||||||
Conf["Enabled Mascots sfw"] = $.get "Enabled Mascots sfw", []
|
'Enabled Mascots': []
|
||||||
Conf["Enabled Mascots nsfw"] = $.get "Enabled Mascots nsfw", []
|
'Enabled Mascots sfw': []
|
||||||
Conf["Deleted Mascots"] = $.get "Deleted Mascots", []
|
'Enabled Mascots nsfw': []
|
||||||
|
'Deleted Mascots': []
|
||||||
|
|
||||||
|
$.get items, (items) ->
|
||||||
|
for key, val of items
|
||||||
|
Conf[key] = val
|
||||||
|
|
||||||
switch location.hostname
|
switch location.hostname
|
||||||
when 'sys.4chan.org'
|
when 'sys.4chan.org'
|
||||||
|
|||||||
@ -33,7 +33,10 @@ Settings =
|
|||||||
lastupdate: Date.now()
|
lastupdate: Date.now()
|
||||||
previousversion: g.VERSION
|
previousversion: g.VERSION
|
||||||
|
|
||||||
Settings.addSection 'Main', Settings.main
|
Settings.addSection 'Style', Settings.style
|
||||||
|
Settings.addSection 'Themes', Settings.themes
|
||||||
|
# Settings.addSection 'Mascots', Settings.mascots
|
||||||
|
Settings.addSection 'Script', Settings.main
|
||||||
Settings.addSection 'Filter', Settings.filter
|
Settings.addSection 'Filter', Settings.filter
|
||||||
Settings.addSection 'Sauce', Settings.sauce
|
Settings.addSection 'Sauce', Settings.sauce
|
||||||
Settings.addSection 'Rice', Settings.rice
|
Settings.addSection 'Rice', Settings.rice
|
||||||
@ -48,6 +51,18 @@ Settings =
|
|||||||
localStorage.setItem '4chan-settings', JSON.stringify settings
|
localStorage.setItem '4chan-settings', JSON.stringify settings
|
||||||
|
|
||||||
open: (openSection) ->
|
open: (openSection) ->
|
||||||
|
if Conf['editMode'] is "theme"
|
||||||
|
if confirm "Opening the options dialog will close and discard any theme changes made with the theme editor."
|
||||||
|
ThemeTools.close()
|
||||||
|
else
|
||||||
|
return
|
||||||
|
|
||||||
|
if Conf['editMode'] is "mascot"
|
||||||
|
if confirm "Opening the options dialog will close and discard any mascot changes made with the mascot editor."
|
||||||
|
MascotTools.close()
|
||||||
|
else
|
||||||
|
return
|
||||||
|
|
||||||
return if Settings.dialog
|
return if Settings.dialog
|
||||||
$.event 'CloseMenu'
|
$.event 'CloseMenu'
|
||||||
|
|
||||||
@ -78,9 +93,8 @@ Settings =
|
|||||||
textContent: section.title
|
textContent: section.title
|
||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
$.on link, 'click', Settings.openSection.bind section
|
$.on link, 'click', Settings.openSection.bind section
|
||||||
links.push link, $.tn ' | '
|
links.push link
|
||||||
sectionToOpen = link if section.title is openSection
|
sectionToOpen = link if section.title is openSection
|
||||||
links.pop()
|
|
||||||
$.add $('.sections-list', overlay), links
|
$.add $('.sections-list', overlay), links
|
||||||
(if sectionToOpen then sectionToOpen else links[0]).click()
|
(if sectionToOpen then sectionToOpen else links[0]).click()
|
||||||
|
|
||||||
@ -91,6 +105,7 @@ Settings =
|
|||||||
d.body.style.width = "#{d.body.clientWidth}px"
|
d.body.style.width = "#{d.body.clientWidth}px"
|
||||||
$.addClass d.body, 'unscroll'
|
$.addClass d.body, 'unscroll'
|
||||||
$.add d.body, overlay
|
$.add d.body, overlay
|
||||||
|
|
||||||
close: ->
|
close: ->
|
||||||
return unless Settings.dialog
|
return unless Settings.dialog
|
||||||
d.body.style.removeProperty 'width'
|
d.body.style.removeProperty 'width'
|
||||||
@ -99,19 +114,21 @@ Settings =
|
|||||||
delete Settings.dialog
|
delete Settings.dialog
|
||||||
|
|
||||||
sections: []
|
sections: []
|
||||||
|
|
||||||
addSection: (title, open) ->
|
addSection: (title, open) ->
|
||||||
if typeof title isnt 'string'
|
if typeof title isnt 'string'
|
||||||
{title, open} = title.detail
|
{title, open} = title.detail
|
||||||
hyphenatedTitle = title.toLowerCase().replace /\s+/g, '-'
|
hyphenatedTitle = title.toLowerCase().replace /\s+/g, '-'
|
||||||
Settings.sections.push {title, hyphenatedTitle, open}
|
Settings.sections.push {title, hyphenatedTitle, open}
|
||||||
openSection: ->
|
|
||||||
|
openSection: (mode)->
|
||||||
if selected = $ '.tab-selected', Settings.dialog
|
if selected = $ '.tab-selected', Settings.dialog
|
||||||
$.rmClass selected, 'tab-selected'
|
$.rmClass selected, 'tab-selected'
|
||||||
$.addClass $(".tab-#{@hyphenatedTitle}", Settings.dialog), 'tab-selected'
|
$.addClass $(".tab-#{@hyphenatedTitle}", Settings.dialog), 'tab-selected'
|
||||||
section = $ 'section', Settings.dialog
|
section = $ 'section', Settings.dialog
|
||||||
section.innerHTML = null
|
section.innerHTML = null
|
||||||
section.className = "section-#{@hyphenatedTitle}"
|
section.className = "section-#{@hyphenatedTitle}"
|
||||||
@open section, g
|
@open section, mode
|
||||||
section.scrollTop = 0
|
section.scrollTop = 0
|
||||||
|
|
||||||
main: (section) ->
|
main: (section) ->
|
||||||
@ -135,12 +152,13 @@ Settings =
|
|||||||
for key, arr of obj
|
for key, arr of obj
|
||||||
description = arr[1]
|
description = arr[1]
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
innerHTML: "<label><input type=checkbox name=\"#{key}\">#{key}</label><span class=description>: #{description}</span>"
|
innerHTML: "<label><input type=checkbox name='#{key}'>#{key}</label><span class=description>: #{description}</span>"
|
||||||
input = $ 'input', div
|
input = $ 'input', div
|
||||||
$.on input, 'change', $.cb.checked
|
$.on input, 'change', $.cb.checked
|
||||||
items[key] = Conf[key]
|
items[key] = Conf[key]
|
||||||
inputs[key] = input
|
inputs[key] = input
|
||||||
$.add fs, div
|
$.add fs, div
|
||||||
|
Rice.nodes fs
|
||||||
$.add section, fs
|
$.add section, fs
|
||||||
|
|
||||||
$.get items, (items) ->
|
$.get items, (items) ->
|
||||||
@ -170,6 +188,7 @@ Settings =
|
|||||||
localStorage.removeItem "4chan-hide-t-#{boardID}"
|
localStorage.removeItem "4chan-hide-t-#{boardID}"
|
||||||
$.delete ['hiddenThreads', 'hiddenPosts']
|
$.delete ['hiddenThreads', 'hiddenPosts']
|
||||||
$.after $('input[name="Stubs"]', section).parentNode.parentNode, div
|
$.after $('input[name="Stubs"]', section).parentNode.parentNode, div
|
||||||
|
|
||||||
export: (now, data) ->
|
export: (now, data) ->
|
||||||
unless typeof now is 'number'
|
unless typeof now is 'number'
|
||||||
now = Date.now()
|
now = Date.now()
|
||||||
@ -197,8 +216,10 @@ Settings =
|
|||||||
p = $ '.imp-exp-result', Settings.dialog
|
p = $ '.imp-exp-result', Settings.dialog
|
||||||
p.innerHTML = null
|
p.innerHTML = null
|
||||||
$.add p, a
|
$.add p, a
|
||||||
|
|
||||||
import: ->
|
import: ->
|
||||||
@nextElementSibling.click()
|
@nextElementSibling.click()
|
||||||
|
|
||||||
onImport: ->
|
onImport: ->
|
||||||
return unless file = @files[0]
|
return unless file = @files[0]
|
||||||
output = @parentNode.nextElementSibling
|
output = @parentNode.nextElementSibling
|
||||||
@ -216,6 +237,7 @@ Settings =
|
|||||||
output.textContent = 'Import failed due to an error.'
|
output.textContent = 'Import failed due to an error.'
|
||||||
c.error err.stack
|
c.error err.stack
|
||||||
reader.readAsText file
|
reader.readAsText file
|
||||||
|
|
||||||
loadSettings: (data) ->
|
loadSettings: (data) ->
|
||||||
version = data.version.split '.'
|
version = data.version.split '.'
|
||||||
if version[0] is '2'
|
if version[0] is '2'
|
||||||
@ -286,6 +308,7 @@ Settings =
|
|||||||
"Shift+#{s[0...-1]}#{s[-1..].toLowerCase()}"
|
"Shift+#{s[0...-1]}#{s[-1..].toLowerCase()}"
|
||||||
data.Conf.WatchedThreads = data.WatchedThreads
|
data.Conf.WatchedThreads = data.WatchedThreads
|
||||||
$.set data.Conf
|
$.set data.Conf
|
||||||
|
|
||||||
convertSettings: (data, map) ->
|
convertSettings: (data, map) ->
|
||||||
for prevKey, newKey of map
|
for prevKey, newKey of map
|
||||||
data.Conf[newKey] = data.Conf[prevKey] if newKey
|
data.Conf[newKey] = data.Conf[prevKey] if newKey
|
||||||
@ -314,6 +337,7 @@ Settings =
|
|||||||
select = $ 'select', section
|
select = $ 'select', section
|
||||||
$.on select, 'change', Settings.selectFilter
|
$.on select, 'change', Settings.selectFilter
|
||||||
Settings.selectFilter.call select
|
Settings.selectFilter.call select
|
||||||
|
|
||||||
selectFilter: ->
|
selectFilter: ->
|
||||||
div = @nextElementSibling
|
div = @nextElementSibling
|
||||||
if (name = @value) isnt 'guide'
|
if (name = @value) isnt 'guide'
|
||||||
@ -440,7 +464,7 @@ Settings =
|
|||||||
items = {}
|
items = {}
|
||||||
inputs = {}
|
inputs = {}
|
||||||
for name in ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']
|
for name in ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']
|
||||||
input = $ "[name=#{name}]", section
|
input = $ "[name='#{name}']", section
|
||||||
items[name] = Conf[name]
|
items[name] = Conf[name]
|
||||||
inputs[name] = input
|
inputs[name] = input
|
||||||
event = if ['favicon', 'usercss'].contains name
|
event = if ['favicon', 'usercss'].contains name
|
||||||
@ -456,15 +480,20 @@ Settings =
|
|||||||
$.on input, event, Settings[key]
|
$.on input, event, Settings[key]
|
||||||
Settings[key].call input
|
Settings[key].call input
|
||||||
return
|
return
|
||||||
|
Rice.nodes section
|
||||||
$.on $('input[name="Custom CSS"]', section), 'change', Settings.togglecss
|
$.on $('input[name="Custom CSS"]', section), 'change', Settings.togglecss
|
||||||
$.on $.id('apply-css'), 'click', Settings.usercss
|
$.on $.id('apply-css'), 'click', Settings.usercss
|
||||||
|
|
||||||
boardnav: ->
|
boardnav: ->
|
||||||
Header.generateBoardList @value
|
Header.generateBoardList @value
|
||||||
|
|
||||||
time: ->
|
time: ->
|
||||||
funk = Time.createFunc @value
|
funk = Time.createFunc @value
|
||||||
@nextElementSibling.textContent = funk Time, new Date()
|
@nextElementSibling.textContent = funk Time, new Date()
|
||||||
|
|
||||||
backlink: ->
|
backlink: ->
|
||||||
@nextElementSibling.textContent = Conf['backlink'].replace /%id/, '123456789'
|
@nextElementSibling.textContent = Conf['backlink'].replace /%id/, '123456789'
|
||||||
|
|
||||||
fileInfo: ->
|
fileInfo: ->
|
||||||
data =
|
data =
|
||||||
isReply: true
|
isReply: true
|
||||||
@ -478,6 +507,7 @@ Settings =
|
|||||||
isSpoiler: true
|
isSpoiler: true
|
||||||
funk = FileInfo.createFunc @value
|
funk = FileInfo.createFunc @value
|
||||||
@nextElementSibling.innerHTML = funk FileInfo, data
|
@nextElementSibling.innerHTML = funk FileInfo, data
|
||||||
|
|
||||||
favicon: ->
|
favicon: ->
|
||||||
Favicon.switch()
|
Favicon.switch()
|
||||||
Unread.update() if g.VIEW is 'thread' and Conf['Unread Tab Icon']
|
Unread.update() if g.VIEW is 'thread' and Conf['Unread Tab Icon']
|
||||||
@ -493,6 +523,7 @@ Settings =
|
|||||||
else
|
else
|
||||||
CustomCSS.addStyle()
|
CustomCSS.addStyle()
|
||||||
$.cb.checked.call @
|
$.cb.checked.call @
|
||||||
|
|
||||||
usercss: ->
|
usercss: ->
|
||||||
CustomCSS.update()
|
CustomCSS.update()
|
||||||
|
|
||||||
@ -517,11 +548,13 @@ Settings =
|
|||||||
items[key] = Conf[key]
|
items[key] = Conf[key]
|
||||||
inputs[key] = input
|
inputs[key] = input
|
||||||
$.on input, 'keydown', Settings.keybind
|
$.on input, 'keydown', Settings.keybind
|
||||||
|
Rice.nodes tr
|
||||||
$.add tbody, tr
|
$.add tbody, tr
|
||||||
$.get items, (items) ->
|
$.get items, (items) ->
|
||||||
for key, val of items
|
for key, val of items
|
||||||
inputs[key].value = val
|
inputs[key].value = val
|
||||||
return
|
return
|
||||||
|
|
||||||
keybind: (e) ->
|
keybind: (e) ->
|
||||||
return if e.keyCode is 9 # tab
|
return if e.keyCode is 9 # tab
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@ -529,3 +562,298 @@ Settings =
|
|||||||
return unless (key = Keybinds.keyCode e)?
|
return unless (key = Keybinds.keyCode e)?
|
||||||
@value = key
|
@value = key
|
||||||
$.cb.value.call @
|
$.cb.value.call @
|
||||||
|
|
||||||
|
style: (section) ->
|
||||||
|
nodes = []
|
||||||
|
|
||||||
|
for key, obj of Config.style
|
||||||
|
|
||||||
|
fs = $.el 'fieldset',
|
||||||
|
innerHTML: "<legend>#{key}</legend>"
|
||||||
|
|
||||||
|
for key, arr of obj
|
||||||
|
[value, description, type] = arr
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
className: 'styleoption'
|
||||||
|
|
||||||
|
if type
|
||||||
|
inputtype = 'value'
|
||||||
|
|
||||||
|
if type is 'text'
|
||||||
|
|
||||||
|
div.innerHTML = "<div class=option><span class=optionlabel>#{key}</span><div style=display: none>#{description}</div></div><div class=option><input name='#{key}' style=width: 100%></div>"
|
||||||
|
input = $ "input[name='#{key}']", div
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
html = "<label><span class=optionlabel>#{key}</span><div style=display: none>#{description}</div></div><div class=option><select name='#{key}'></label>"
|
||||||
|
for name, val in type
|
||||||
|
html += "<option value='#{val}'>#{name}</option>"
|
||||||
|
html += "</select>"
|
||||||
|
div.innerHTML = html
|
||||||
|
input = $ "select", div
|
||||||
|
|
||||||
|
else
|
||||||
|
inputtype = 'checked'
|
||||||
|
|
||||||
|
div.innerHTML = "<label><input type=checkbox name='#{key}'>#{key}</label><span class=description>: #{description}</span>"
|
||||||
|
input = $ 'input', div
|
||||||
|
|
||||||
|
Settings.sandbox input, key, value, inputtype
|
||||||
|
|
||||||
|
$.on input, 'change', ->
|
||||||
|
$.cb[inputtype].call @
|
||||||
|
Style.addStyle()
|
||||||
|
|
||||||
|
Rice.nodes fs
|
||||||
|
$.add fs, div
|
||||||
|
|
||||||
|
nodes.push fs
|
||||||
|
|
||||||
|
$.add section, nodes
|
||||||
|
|
||||||
|
sandbox: (input, key, value, inputtype) ->
|
||||||
|
$.get key, value, (item) ->
|
||||||
|
input[inputtype] = item[key]
|
||||||
|
|
||||||
|
themes: (section, mode) ->
|
||||||
|
if typeof mode isnt 'string'
|
||||||
|
mode = 'default'
|
||||||
|
|
||||||
|
parentdiv = $.el 'div',
|
||||||
|
id: "themeContainer"
|
||||||
|
|
||||||
|
suboptions = $.el 'div',
|
||||||
|
className: "suboptions"
|
||||||
|
id: "themes"
|
||||||
|
|
||||||
|
keys = Object.keys(Themes)
|
||||||
|
keys.sort()
|
||||||
|
|
||||||
|
if mode is "default"
|
||||||
|
|
||||||
|
for name in keys
|
||||||
|
theme = Themes[name]
|
||||||
|
|
||||||
|
unless theme["Deleted"]
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
className: "theme #{if name is Conf['theme'] then 'selectedtheme' else ''}"
|
||||||
|
id: name
|
||||||
|
innerHTML: "
|
||||||
|
<div style='cursor: pointer; position: relative; margin-bottom: 2px; width: 100% !important; box-shadow: none !important; background:#{theme['Reply Background']}!important;border:1px solid #{theme['Reply Border']}!important;color:#{theme['Text']}!important'>
|
||||||
|
<div>
|
||||||
|
<div style='cursor: pointer; width: 9px; height: 9px; margin: 2px 3px; display: inline-block; vertical-align: bottom; background: #{theme['Checkbox Background']}; border: 1px solid #{theme['Checkbox Border']};'></div>
|
||||||
|
<span style='color:#{theme['Subjects']}!important; font-weight: 600 !important'>
|
||||||
|
#{name}
|
||||||
|
</span>
|
||||||
|
<span style='color:#{theme['Names']}!important; font-weight: 600 !important'>
|
||||||
|
#{theme['Author']}
|
||||||
|
</span>
|
||||||
|
<span style='color:#{theme['Sage']}!important'>
|
||||||
|
(SAGE)
|
||||||
|
</span>
|
||||||
|
<span style='color:#{theme['Tripcodes']}!important'>
|
||||||
|
#{theme['Author Tripcode']}
|
||||||
|
</span>
|
||||||
|
<time style='color:#{theme['Timestamps']}'>
|
||||||
|
20XX.01.01 12:00
|
||||||
|
</time>
|
||||||
|
<a onmouseout='this.setAttribute("style","color:#{theme['Post Numbers']}!important")' onmouseover='this.setAttribute("style","color:#{theme['Hovered Links']}!important;")' style='color:#{theme['Post Numbers']}!important;' href='javascript:;'>
|
||||||
|
No.27583594
|
||||||
|
</a>
|
||||||
|
<a onmouseout='this.setAttribute("style","color:#{theme['Backlinks']}!important;")' onmouseover='this.setAttribute("style","color:#{theme['Hovered Links']}!important;")' style='color:#{theme['Backlinks']}!important;' href='javascript:;' name='#{name}' class=edit>
|
||||||
|
>>edit
|
||||||
|
</a>
|
||||||
|
<a onmouseout='this.setAttribute("style","color:#{theme['Backlinks']}!important;")' onmouseover='this.setAttribute("style","color:#{theme['Hovered Links']}!important;")' style='color:#{theme['Backlinks']}!important;' href='javascript:;' name='#{name}' class=export>
|
||||||
|
>>export
|
||||||
|
</a>
|
||||||
|
<a onmouseout='this.setAttribute("style","color:#{theme['Backlinks']}!important;")' onmouseover='this.setAttribute("style","color:#{theme['Hovered Links']}!important;")' style='color:#{theme['Backlinks']}!important;' href='javascript:;' name='#{name}' class=delete>
|
||||||
|
>>delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<blockquote style='margin: 0; padding: 12px 40px 12px 38px'>
|
||||||
|
<a style='color:#{theme['Quotelinks']}!important; text-shadow: none;'>
|
||||||
|
>>27582902
|
||||||
|
</a>
|
||||||
|
<br>
|
||||||
|
Post content is right here.
|
||||||
|
</blockquote>
|
||||||
|
<h1 style='color: #{theme['Text']}'>
|
||||||
|
Selected
|
||||||
|
</h1>
|
||||||
|
</div>"
|
||||||
|
|
||||||
|
div.style.backgroundColor = theme['Background Color']
|
||||||
|
|
||||||
|
$.on $('a.edit', div), 'click', (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
ThemeTools.init @name
|
||||||
|
Settings.close()
|
||||||
|
|
||||||
|
$.on $('a.export', div), 'click', (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
exportTheme = Themes[@name]
|
||||||
|
exportTheme['Theme'] = @name
|
||||||
|
exportedTheme = "data:application/json," + encodeURIComponent(JSON.stringify(exportTheme))
|
||||||
|
|
||||||
|
if window.open exportedTheme, "_blank"
|
||||||
|
return
|
||||||
|
else if confirm "Your popup blocker is preventing Appchan X from exporting this theme. Would you like to open the exported theme in this window?"
|
||||||
|
window.location exportedTheme
|
||||||
|
|
||||||
|
$.on $('a.delete', div), 'click', (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
container = $.id @name
|
||||||
|
|
||||||
|
unless container.previousSibling or container.nextSibling
|
||||||
|
alert "Cannot delete theme (No other themes available)."
|
||||||
|
return
|
||||||
|
|
||||||
|
if confirm "Are you sure you want to delete \"#{@name}\"?"
|
||||||
|
if @name is Conf['theme']
|
||||||
|
if settheme = container.previousSibling or container.nextSibling
|
||||||
|
Conf['theme'] = settheme.id
|
||||||
|
$.addClass settheme, 'selectedtheme'
|
||||||
|
$.set 'theme', Conf['theme']
|
||||||
|
Themes[@name]["Deleted"] = true
|
||||||
|
userThemes = $.get "userThemes", {}
|
||||||
|
userThemes[@name] = Themes[@name]
|
||||||
|
$.set 'userThemes', userThemes
|
||||||
|
$.rm container
|
||||||
|
|
||||||
|
$.on div, 'click', Settings.selectTheme
|
||||||
|
$.add suboptions, div
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
id: 'addthemes'
|
||||||
|
innerHTML: "
|
||||||
|
<a id=newtheme href='javascript:;'>New Theme</a> /
|
||||||
|
<a id=import href='javascript:;'>Import Theme</a><input id=importbutton type=file hidden> /
|
||||||
|
<a id=SSimport href='javascript:;'>Import from 4chan SS</a><input id=SSimportbutton type=file hidden> /
|
||||||
|
<a id=OCimport href='javascript:;'>Import from Oneechan</a><input id=OCimportbutton type=file hidden> /
|
||||||
|
<a id=tUndelete href='javascript:;'>Undelete Theme</a>
|
||||||
|
"
|
||||||
|
|
||||||
|
$.on $("#newtheme", div), 'click', ->
|
||||||
|
ThemeTools.init "untitled"
|
||||||
|
Settings.close()
|
||||||
|
|
||||||
|
$.on $("#import", div), 'click', ->
|
||||||
|
@nextSibling.click()
|
||||||
|
$.on $("#importbutton", div), 'change', (evt) ->
|
||||||
|
ThemeTools.importtheme "appchan", evt
|
||||||
|
|
||||||
|
$.on $("#OCimport", div), 'click', ->
|
||||||
|
@nextSibling.click()
|
||||||
|
$.on $("#OCimportbutton", div), 'change', (evt) ->
|
||||||
|
ThemeTools.importtheme "oneechan", evt
|
||||||
|
|
||||||
|
$.on $("#SSimportbutton", div), 'change', (evt) ->
|
||||||
|
ThemeTools.importtheme "SS", evt
|
||||||
|
$.on $("#SSimport", div), 'click', ->
|
||||||
|
@nextSibling.click()
|
||||||
|
|
||||||
|
$.on $('#tUndelete', div), 'click', ->
|
||||||
|
$.rm $.id "themeContainer"
|
||||||
|
Settings.openSection themes, 'undelete'
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
for name in keys
|
||||||
|
theme = Themes[name]
|
||||||
|
|
||||||
|
if theme["Deleted"]
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
id: name
|
||||||
|
className: theme
|
||||||
|
innerHTML: "
|
||||||
|
<div style='cursor: pointer; position: relative; margin-bottom: 2px; width: 100% !important; box-shadow: none !important; background:#{theme['Reply Background']}!important;border:1px solid #{theme['Reply Border']}!important;color:#{theme['Text']}!important'>
|
||||||
|
<div style='padding: 3px 0px 0px 8px;'>
|
||||||
|
<span style='color:#{theme['Subjects']}!important; font-weight: 600 !important'>#{name}</span>
|
||||||
|
<span style='color:#{theme['Names']}!important; font-weight: 600 !important'>#{theme['Author']}</span>
|
||||||
|
<span style='color:#{theme['Sage']}!important'>(SAGE)</span>
|
||||||
|
<span style='color:#{theme['Tripcodes']}!important'>#{theme['Author Tripcode']}</span>
|
||||||
|
<time style='color:#{theme['Timestamps']}'>20XX.01.01 12:00</time>
|
||||||
|
<a onmouseout='this.setAttribute("style","color:#{theme['Post Numbers']}!important")' onmouseover='this.setAttribute("style","color:#{theme['Hovered Links']}!important")' style='color:#{theme['Post Numbers']}!important;' href='javascript:;'>No.27583594</a>
|
||||||
|
</div>
|
||||||
|
<blockquote style='margin: 0; padding: 12px 40px 12px 38px'>
|
||||||
|
<a style='color:#{theme['Quotelinks']}!important; text-shadow: none;'>
|
||||||
|
>>27582902
|
||||||
|
</a>
|
||||||
|
<br>
|
||||||
|
I forgive you for using VLC to open me. ;__;
|
||||||
|
</blockquote>
|
||||||
|
</div>"
|
||||||
|
|
||||||
|
$.on div, 'click', ->
|
||||||
|
if confirm "Are you sure you want to undelete \"#{@id}\"?"
|
||||||
|
Themes[@id]["Deleted"] = false
|
||||||
|
$.get "userThemes", {}, (item) ->
|
||||||
|
userThemes = item["userThemes"]
|
||||||
|
userThemes[@id] = Themes[@id]
|
||||||
|
$.set 'userThemes', userThemes
|
||||||
|
$.rm @
|
||||||
|
|
||||||
|
$.add suboptions, div
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
id: 'addthemes'
|
||||||
|
innerHTML: "<a href='javascript:;'>Return</a>"
|
||||||
|
|
||||||
|
$.on $('a', div), 'click', ->
|
||||||
|
$.rm $.id "themeContainer"
|
||||||
|
Settings.openSection themes
|
||||||
|
|
||||||
|
$.add parentdiv, suboptions
|
||||||
|
$.add parentdiv, div
|
||||||
|
$.add section, parentdiv
|
||||||
|
|
||||||
|
selectTheme: ->
|
||||||
|
if currentTheme = $.id(Conf['theme'])
|
||||||
|
$.rmClass currentTheme, 'selectedtheme'
|
||||||
|
|
||||||
|
if Conf["NSFW/SFW Themes"]
|
||||||
|
$.set "theme_#{g.TYPE}", @id
|
||||||
|
else
|
||||||
|
$.set "theme", @id
|
||||||
|
Conf['theme'] = @id
|
||||||
|
$.addClass @, 'selectedtheme'
|
||||||
|
Style.addStyle()
|
||||||
|
|
||||||
|
mouseover: (e) ->
|
||||||
|
if mouseover = $.id 'mouseover'
|
||||||
|
if children = mouseover.childNodes
|
||||||
|
for child in children
|
||||||
|
$.rm child
|
||||||
|
else
|
||||||
|
mouseover = $.el 'div',
|
||||||
|
id: 'mouseover'
|
||||||
|
className: 'dialog'
|
||||||
|
|
||||||
|
$.add d.body, mouseover
|
||||||
|
|
||||||
|
mouseover.innerHTML = @nextElementSibling.innerHTML
|
||||||
|
|
||||||
|
UI.el = mouseover
|
||||||
|
|
||||||
|
$.on @, 'mousemove', Settings.hover
|
||||||
|
$.on @, 'mouseout', Settings.mouseout
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
hover: (e) ->
|
||||||
|
UI.hover e, "menu"
|
||||||
|
|
||||||
|
mouseout: (e) ->
|
||||||
|
mouseover = UI.el
|
||||||
|
for child in mouseover.childNodes
|
||||||
|
$.rm child
|
||||||
|
delete UI.el
|
||||||
|
|
||||||
|
$.off @, 'mousemove', Settings.hover
|
||||||
Loading…
x
Reference in New Issue
Block a user