Merge branch 'v3' of git://github.com/MayhemYDG/4chan-x into v3
Conflicts: Gruntfile.js src/config.coffee src/css/style.css src/features.coffee src/main.coffee
This commit is contained in:
commit
a067ad6262
@ -1,3 +1,10 @@
|
||||
## 3.2.0 - *2013-04-23*
|
||||
|
||||
- The top and bottom original board lists are now optional, disabled by default.
|
||||
- The button to show a hidden announcement is now inside the header's menu.
|
||||
- Reorganized Header menu:<br>
|
||||
- Added the `board-replace` setting to Custom Board Navigation ricing.
|
||||
- Added the option `Cooldown Prediction`, enabled by default.
|
||||
- Added the option `Hide Unread Count at (0)`, disabled by default.
|
||||
|
||||
### 3.1.4 - *2013-04-17*
|
||||
|
||||
@ -189,7 +189,7 @@ module.exports = (grunt) ->
|
||||
grunt.registerTask 'reloadPkg', 'Reload the package', ->
|
||||
# Update the `pkg` object with the new version.
|
||||
pkg = grunt.file.readJSON('package.json')
|
||||
concatOptions.process.data = pkg
|
||||
grunt.config.data.pkg = concatOptions.process.data = pkg
|
||||
grunt.log.ok('pkg reloaded.')
|
||||
|
||||
grunt.registerTask 'updcl', 'Update the changelog', (i) ->
|
||||
|
||||
194
Gruntfile.js
Normal file
194
Gruntfile.js
Normal file
@ -0,0 +1,194 @@
|
||||
module.exports = function(grunt) {
|
||||
|
||||
var pkg = grunt.file.readJSON('package.json');
|
||||
var concatOptions = {
|
||||
process: {
|
||||
data: pkg
|
||||
}
|
||||
};
|
||||
var shellOptions = {
|
||||
stdout: true,
|
||||
stderr: true,
|
||||
failOnError: true
|
||||
};
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
pkg: pkg,
|
||||
concat: {
|
||||
coffee: {
|
||||
options: concatOptions,
|
||||
src: [
|
||||
'src/config.coffee',
|
||||
'src/globals.coffee',
|
||||
'lib/ui.coffee',
|
||||
'lib/$.coffee',
|
||||
'lib/polyfill.coffee',
|
||||
'src/features.coffee',
|
||||
'src/qr.coffee',
|
||||
'src/report.coffee',
|
||||
'src/databoard.coffee',
|
||||
'src/main.coffee'
|
||||
],
|
||||
dest: 'tmp-<%= pkg.type %>/script.coffee'
|
||||
},
|
||||
crx: {
|
||||
options: concatOptions,
|
||||
files: {
|
||||
'builds/crx/manifest.json': 'src/manifest.json',
|
||||
'builds/crx/script.js': [
|
||||
'src/banner.js',
|
||||
'tmp-<%= pkg.type %>/script.js'
|
||||
]
|
||||
}
|
||||
},
|
||||
userjs: {
|
||||
options: concatOptions,
|
||||
src: [
|
||||
'src/metadata.js',
|
||||
'src/banner.js',
|
||||
'tmp-<%= pkg.type %>/script.js'
|
||||
],
|
||||
dest: 'builds/<%= pkg.name %>.js'
|
||||
},
|
||||
userscript: {
|
||||
options: concatOptions,
|
||||
files: {
|
||||
'builds/<%= pkg.name %>.meta.js': 'src/metadata.js',
|
||||
'builds/<%= pkg.name %>.user.js': [
|
||||
'src/metadata.js',
|
||||
'src/banner.js',
|
||||
'tmp-<%= pkg.type %>/script.js'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
copy: {
|
||||
crx: {
|
||||
src: 'img/*.png',
|
||||
dest: 'builds/crx/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
}
|
||||
},
|
||||
coffee: {
|
||||
script: {
|
||||
src: 'tmp-<%= pkg.type %>/script.coffee',
|
||||
dest: 'tmp-<%= pkg.type %>/script.js'
|
||||
}
|
||||
},
|
||||
concurrent: {
|
||||
build: ['build-crx', 'build-userjs', 'build-userscript']
|
||||
},
|
||||
shell: {
|
||||
commit: {
|
||||
options: shellOptions,
|
||||
command: [
|
||||
'git checkout <%= pkg.meta.mainBranch %>',
|
||||
'git commit -am "Release <%= pkg.meta.name %> v<%= pkg.version %>."',
|
||||
'git tag -a <%= pkg.version %> -m "<%= pkg.meta.name %> v<%= pkg.version %>."',
|
||||
'git tag -af stable-v3 -m "<%= pkg.meta.name %> v<%= pkg.version %>."'
|
||||
].join(' && ')
|
||||
},
|
||||
push: {
|
||||
options: shellOptions,
|
||||
command: 'git push origin --tags -f && git push origin --all'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
all: {
|
||||
options: {
|
||||
interrupt: true
|
||||
},
|
||||
files: [
|
||||
'Gruntfile.js',
|
||||
'package.json',
|
||||
'lib/**/*',
|
||||
'src/**/*',
|
||||
'css/**/*',
|
||||
'img/**/*'
|
||||
],
|
||||
tasks: 'build'
|
||||
}
|
||||
},
|
||||
compress: {
|
||||
crx: {
|
||||
options: {
|
||||
archive: 'builds/<%= pkg.name %>.zip',
|
||||
level: 9,
|
||||
pretty: true
|
||||
},
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: 'builds/crx/*',
|
||||
dest: '/'
|
||||
}
|
||||
},
|
||||
clean: {
|
||||
builds: 'builds',
|
||||
tmpcrx: 'tmp-crx',
|
||||
tmpuserjs: 'tmp-userjs',
|
||||
tmpuserscript: 'tmp-userscript'
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-bump');
|
||||
grunt.loadNpmTasks('grunt-concurrent');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-coffee');
|
||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-shell');
|
||||
|
||||
grunt.registerTask('default', ['build']);
|
||||
|
||||
grunt.registerTask('set-build', 'Set the build type variable', function(type) {
|
||||
pkg.type = type;
|
||||
grunt.log.ok('pkg.type = %s', type);
|
||||
});
|
||||
grunt.registerTask('build', ['concurrent:build']);
|
||||
grunt.registerTask('build-crx', [
|
||||
'set-build:crx',
|
||||
'concat:coffee',
|
||||
'coffee:script',
|
||||
'concat:crx',
|
||||
'copy:crx',
|
||||
'clean:tmpcrx'
|
||||
]);
|
||||
grunt.registerTask('build-userjs', [
|
||||
'set-build:userjs',
|
||||
'concat:coffee',
|
||||
'coffee:script',
|
||||
'concat:userjs',
|
||||
'clean:tmpuserjs'
|
||||
]);
|
||||
grunt.registerTask('build-userscript', [
|
||||
'set-build:userscript',
|
||||
'concat:coffee',
|
||||
'coffee:script',
|
||||
'concat:userscript',
|
||||
'clean:tmpuserscript'
|
||||
]);
|
||||
|
||||
grunt.registerTask('release', ['shell:commit', 'shell:push', 'build-crx', 'compress:crx']);
|
||||
grunt.registerTask('patch', ['bump', 'reloadPkg', 'updcl:3', 'release']);
|
||||
grunt.registerTask('minor', ['bump:minor', 'reloadPkg', 'updcl:2', 'release']);
|
||||
grunt.registerTask('major', ['bump:major', 'reloadPkg', 'updcl:1', 'release']);
|
||||
|
||||
grunt.registerTask('reloadPkg', 'Reload the package', function() {
|
||||
// Update the `pkg` object with the new version.
|
||||
pkg = grunt.file.readJSON('package.json');
|
||||
grunt.config.data.pkg = concatOptions.process.data = pkg;
|
||||
grunt.log.ok('pkg reloaded.');
|
||||
});
|
||||
|
||||
grunt.registerTask('updcl', 'Update the changelog', function(i) {
|
||||
// i is the number of #s for markdown.
|
||||
var version = new Array(+i + 1).join('#') + ' ' + pkg.version + ' - *' + grunt.template.today('yyyy-mm-dd') + '*';
|
||||
grunt.file.write('CHANGELOG.md', version + '\n\n' + grunt.file.read('CHANGELOG.md'));
|
||||
grunt.log.ok('Changelog updated for v' + pkg.version + '.');
|
||||
});
|
||||
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan X",
|
||||
"version": "3.1.4",
|
||||
"version": "3.2.0",
|
||||
"manifest_version": 2,
|
||||
"description": "Cross-browser extension for productive lurking on 4chan.",
|
||||
"icons": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
BIN
img/changelog/3.2.0/0.png
Normal file
BIN
img/changelog/3.2.0/0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan-X",
|
||||
"version": "3.1.4",
|
||||
"version": "3.2.0",
|
||||
"description": "Cross-browser extension for productive lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
@ -20,8 +20,8 @@
|
||||
"grunt-bump": "~0.0.2",
|
||||
"grunt-concurrent": "~0.2.0",
|
||||
"grunt-contrib-clean": "~0.4.1",
|
||||
"grunt-contrib-coffee": "~0.6.7",
|
||||
"grunt-contrib-compress": "~0.4.10",
|
||||
"grunt-contrib-coffee": "~0.7.0",
|
||||
"grunt-contrib-compress": "~0.5.0",
|
||||
"grunt-contrib-concat": "~0.2.0",
|
||||
"grunt-contrib-copy": "~0.4.1",
|
||||
"grunt-contrib-watch": "~0.3.1",
|
||||
|
||||
@ -9,10 +9,6 @@ Config =
|
||||
false
|
||||
'Link to external catalog instead of the internal one.'
|
||||
]
|
||||
'Custom Board Navigation': [
|
||||
true
|
||||
'Show custom links instead of the full board list.'
|
||||
]
|
||||
'QR Shortcut': [
|
||||
false,
|
||||
'Adds a small [QR] link in the header.'
|
||||
@ -257,6 +253,10 @@ Config =
|
||||
true
|
||||
'Prevent "flood detected" errors.'
|
||||
]
|
||||
'Cooldown Prediction': [
|
||||
true
|
||||
'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'
|
||||
]
|
||||
|
||||
'Quote Links':
|
||||
'Quote Backlinks': [
|
||||
@ -388,13 +388,13 @@ http://iqdb.org/?url=%TURL
|
||||
|
||||
'Custom CSS': false
|
||||
|
||||
'Boards Navigation': 'Sticky top'
|
||||
|
||||
'Header auto-hide': false
|
||||
|
||||
'Footer auto-hide': true
|
||||
|
||||
'Header catalog links': false
|
||||
Header:
|
||||
'Fixed Header': true
|
||||
'Header auto-hide': false
|
||||
'Bottom Header': false
|
||||
'Header catalog links': false
|
||||
'Bottom Board List': false
|
||||
'Custom Board Navigation': false
|
||||
|
||||
boardnav: '[ toggle-all ] [current-title]'
|
||||
|
||||
|
||||
@ -47,6 +47,9 @@ a[href="javascript:;"] {
|
||||
.warning {
|
||||
color: red;
|
||||
}
|
||||
#boardNavDesktop {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 4chan style fixes */
|
||||
.opContainer, .op {
|
||||
@ -367,6 +370,9 @@ a[href="javascript:;"] {
|
||||
a.hide-announcement {
|
||||
float: left;
|
||||
}
|
||||
#toggleMsgBtn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Unread */
|
||||
#unread-line {
|
||||
@ -868,4 +874,4 @@ a:only-of-type > .remove {
|
||||
.export, .import {
|
||||
cursor: pointer;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,20 @@ PSAHiding =
|
||||
init: ->
|
||||
return if !Conf['Announcement Hiding']
|
||||
|
||||
entry =
|
||||
type: 'header'
|
||||
el: $.el 'a',
|
||||
textContent: 'Show announcement'
|
||||
className: 'show-announcement'
|
||||
href: 'javascript:;'
|
||||
order: 50
|
||||
open: ->
|
||||
if $.id('globalMessage')?.hidden
|
||||
return true
|
||||
false
|
||||
$.event 'AddMenuEntry', entry
|
||||
|
||||
$.on entry.el, 'click', PSAHiding.toggle
|
||||
$.addClass doc, 'hide-announcement'
|
||||
|
||||
$.on d, '4chanXInitFinished', @setup
|
||||
@ -14,12 +28,12 @@ PSAHiding =
|
||||
return
|
||||
|
||||
PSAHiding.btn = btn = $.el 'a',
|
||||
title: 'Toggle announcement.'
|
||||
innerHTML: '<span></span>'
|
||||
innerHTML: '<span>[ - ]</span>'
|
||||
title: 'Hide announcement.'
|
||||
className: 'hide-announcement'
|
||||
href: 'javascript:;'
|
||||
$.on btn, 'click', PSAHiding.toggle
|
||||
|
||||
text = PSAHiding.trim psa
|
||||
$.get 'hiddenPSAs', [], (item) ->
|
||||
PSAHiding.sync item['hiddenPSAs']
|
||||
$.before psa, btn
|
||||
@ -33,19 +47,21 @@ PSAHiding =
|
||||
$.get 'hiddenPSAs', [], ({hiddenPSAs}) ->
|
||||
if hide
|
||||
hiddenPSAs.push text
|
||||
hiddenPSAs = hiddenPSAs[-5..]
|
||||
else
|
||||
$.event 'CloseMenu'
|
||||
i = hiddenPSAs.indexOf text
|
||||
hiddenPSAs.splice i, 1
|
||||
hiddenPSAs = hiddenPSAs[-5..]
|
||||
PSAHiding.sync hiddenPSAs
|
||||
$.set 'hiddenPSAs', hiddenPSAs
|
||||
|
||||
sync: (hiddenPSAs) ->
|
||||
{btn} = PSAHiding
|
||||
psa = $.id 'globalMessage'
|
||||
[psa.hidden, btn.firstChild.textContent, btn.className] = if PSAHiding.trim(psa) in hiddenPSAs
|
||||
[true, '[\u00A0+\u00A0]', 'show-announcement']
|
||||
psa = $.id 'globalMessage'
|
||||
psa.hidden = PSAHiding.btn.hidden = if PSAHiding.trim(psa) in hiddenPSAs
|
||||
true
|
||||
else
|
||||
[false, '[\u00A0-\u00A0]', 'hide-announcement']
|
||||
false
|
||||
if hr = $.x 'following-sibling::hr', psa
|
||||
hr.hidden = psa.hidden
|
||||
trim: (psa) ->
|
||||
psa.textContent.replace(/\W+/g, '').toLowerCase()
|
||||
@ -27,7 +27,11 @@ CatalogLinks =
|
||||
|
||||
set: (useCatalog) ->
|
||||
path = if useCatalog then 'catalog' else ''
|
||||
for a in $$ 'a', $.id('board-list')
|
||||
for a in $$ """
|
||||
#board-list a[href*="boards.4chan.org"],
|
||||
#boardNavDesktop a[href*="boards.4chan.org"],
|
||||
#boardNavDesktopFoot a[href*="boards.4chan.org"]
|
||||
"""
|
||||
board = a.pathname.split('/')[1]
|
||||
continue if ['f', 'status', '4chan'].contains(board) or !board
|
||||
if Conf['External Catalog']
|
||||
|
||||
@ -1,26 +1,45 @@
|
||||
Header =
|
||||
init: ->
|
||||
@menu = new UI.Menu 'header'
|
||||
@menuButton = $.el 'span',
|
||||
className: 'menu-button'
|
||||
innerHTML: '<i></i>'
|
||||
|
||||
@menu = new UI.Menu 'header'
|
||||
|
||||
barFixedToggler = $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Fixed Header"> Fixed Header'
|
||||
headerToggler = $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Header auto-hide"> Auto-hide header'
|
||||
barPositionToggler = $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Bottom header"> Bottom header'
|
||||
customNavToggler = $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Custom Board Navigation"> Custom board navigation'
|
||||
footerToggler = $.el 'label',
|
||||
innerHTML: "<input type=checkbox #{unless Conf['Bottom Board List'] then 'checked' else ''}> Hide Footer Nav"
|
||||
editCustomNav = $.el 'a',
|
||||
textContent: 'Edit custom board navigation'
|
||||
href: 'javascript:;'
|
||||
|
||||
@headerToggler = headerToggler.firstElementChild
|
||||
@barFixedToggler = barFixedToggler.firstElementChild
|
||||
@barPositionToggler = barPositionToggler.firstElementChild
|
||||
@headerToggler = headerToggler.firstElementChild
|
||||
@footerToggler = footerToggler.firstElementChild
|
||||
@customNavToggler = customNavToggler.firstElementChild
|
||||
|
||||
$.on @menuButton, 'click', @menuToggle
|
||||
$.on window, 'load hashchange', Header.hashScroll
|
||||
$.on @headerToggler, 'change', @toggleBarVisibility
|
||||
$.on @menuButton, 'click', @menuToggle
|
||||
$.on @barFixedToggler, 'change', @toggleBarFixed
|
||||
$.on @barPositionToggler, 'change', @toggleBarPosition
|
||||
$.on @headerToggler, 'change', @toggleBarVisibility
|
||||
$.on @footerToggler, 'change', @toggleFooterVisibility
|
||||
$.on @customNavToggler, 'change', @toggleCustomNav
|
||||
$.on editCustomNav, 'click', @editCustomNav
|
||||
|
||||
{createSubEntry} = Header
|
||||
subEntries = []
|
||||
for setting in ['Sticky top', 'Sticky bottom', 'Top']
|
||||
subEntries.push createSubEntry setting
|
||||
@setBarFixed Conf['Fixed Header']
|
||||
@setBarVisibility Conf['Header auto-hide']
|
||||
@setBarPosition Conf['Bottom Header']
|
||||
|
||||
subEntries.push {el: headerToggler}
|
||||
$.sync 'Fixed Header', Header.setBarFixed
|
||||
$.sync 'Bottom Header', Header.setBarPosition
|
||||
$.sync 'Header auto-hide', Header.setBarVisibility
|
||||
|
||||
@addShortcut Header.menuButton
|
||||
|
||||
@ -29,32 +48,38 @@ Header =
|
||||
el: $.el 'span',
|
||||
textContent: 'Header'
|
||||
order: 105
|
||||
subEntries: subEntries
|
||||
|
||||
@footerToggler = $.el 'label',
|
||||
innerHTML: "<input type=checkbox #{if Conf['Footer auto-hide'] then 'checked' else ''}> Hide Footer Nav"
|
||||
$.on @footerToggler.firstElementChild, 'change', @toggleFooterVisibility
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
el: @footerToggler
|
||||
order: 100
|
||||
subEntries: [
|
||||
{el: barFixedToggler}
|
||||
{el: headerToggler}
|
||||
{el: barPositionToggler}
|
||||
{el: footerToggler}
|
||||
{el: customNavToggler}
|
||||
{el: editCustomNav}
|
||||
]
|
||||
|
||||
$.on window, 'load hashchange', Header.hashScroll
|
||||
$.on d, 'CreateNotification', @createNotification
|
||||
|
||||
$.asap (-> d.body), ->
|
||||
$.asap (-> d.body), =>
|
||||
return unless Main.isThisPageLegit()
|
||||
# Wait for #boardNavMobile instead of #boardNavDesktop,
|
||||
# it might be incomplete otherwise.
|
||||
$.asap (-> $.id 'boardNavMobile'), Header.setBoardList
|
||||
$.asap (-> $.id('boardNavMobile') or d.readyState is 'complete'), Header.setBoardList
|
||||
$.prepend d.body, @bar
|
||||
|
||||
$.ready ->
|
||||
$.add d.body, Header.hover
|
||||
Header.footer = footer = $.id 'boardNavDesktopFoot'
|
||||
Header.setFooterVisibility Conf['Footer auto-hide']
|
||||
$.sync 'Footer auto-hide', Header.setFooterVisibility
|
||||
$.ready =>
|
||||
if a = $ "a[href*='/#{g.BOARD}/']", $.id 'boardNavDesktopFoot'
|
||||
a.className = 'current'
|
||||
|
||||
$.add d.body, @hover
|
||||
@footer = $.id 'boardNavDesktopFoot'
|
||||
@setFooterVisibility !Conf['Bottom Board List']
|
||||
$.sync 'Bottom Board List', Header.setFooterVisibility
|
||||
|
||||
bar: $.el 'div',
|
||||
id: 'header-bar'
|
||||
|
||||
notify: $.el 'div',
|
||||
id: 'notifications'
|
||||
|
||||
shortcuts: $.el 'span',
|
||||
@ -66,61 +91,33 @@ Header =
|
||||
toggle: $.el 'div',
|
||||
id: 'scroll-marker'
|
||||
|
||||
createSubEntry: (setting) ->
|
||||
label = $.el 'label',
|
||||
textContent: "#{setting}"
|
||||
|
||||
$.on label, 'click', Header.setBarPosition
|
||||
|
||||
el: label
|
||||
|
||||
setBoardList: ->
|
||||
Header.nav = nav = $.id 'boardNavDesktop'
|
||||
nav.id = 'header-bar'
|
||||
if a = $ "a[href*='/#{g.BOARD}/']", nav
|
||||
fourchannav = $.id 'boardNavDesktop'
|
||||
if a = $ "a[href*='/#{g.BOARD}/']", fourchannav
|
||||
a.className = 'current'
|
||||
|
||||
boardList = $.el 'span',
|
||||
id: 'board-list'
|
||||
innerHTML: "<span id=custom-board-list></span><span id=full-board-list hidden>[<a href=javascript:; class='hide-board-list-button'> - </a>]#{fourchannav.innerHTML}</span>"
|
||||
fullBoardList = $ '#full-board-list', boardList
|
||||
btn = $ '.hide-board-list-button', fullBoardList
|
||||
$.on btn, 'click', Header.toggleBoardList
|
||||
|
||||
$.add boardList, fullBoardList = $.el 'span',
|
||||
id: 'full-board-list'
|
||||
$.rm $ '#navtopright', fullBoardList
|
||||
$.add boardList, fullBoardList
|
||||
$.add Header.bar, [boardList, Header.shortcuts, Header.notify, Header.toggle]
|
||||
|
||||
Header.setBarPosition.call textContent: "#{Conf['Boards Navigation']}"
|
||||
$.sync 'Boards Navigation', Header.changeBarPosition
|
||||
Header.setCustomNav Conf['Custom Board Navigation']
|
||||
Header.generateBoardList Conf['boardnav']
|
||||
|
||||
Header.setBarVisibility Conf['Header auto-hide']
|
||||
$.sync 'Header auto-hide', Header.setBarVisibility
|
||||
|
||||
$.add fullBoardList, [nav.childNodes...]
|
||||
$.add nav, [boardList, Header.shortcuts, Header.bar, Header.toggle]
|
||||
|
||||
if Conf['Custom Board Navigation']
|
||||
fullBoardList.hidden = true
|
||||
customBoardList = $.el 'span',
|
||||
id: 'custom-board-list'
|
||||
$.add boardList, customBoardList
|
||||
|
||||
Header.generateBoardList Conf['boardnav']
|
||||
$.sync 'boardnav', Header.generateBoardList
|
||||
|
||||
btn = $.el 'span',
|
||||
className: 'hide-board-list-button'
|
||||
innerHTML: '[<a href=javascript:;> - </a>]\u00A0'
|
||||
$.on btn, 'click', Header.toggleBoardList
|
||||
|
||||
$.prepend fullBoardList, btn
|
||||
|
||||
else
|
||||
fullBoardList.hidden = false
|
||||
$.sync 'Custom Board Navigation', Header.setCustomNav
|
||||
$.sync 'boardnav', Header.generateBoardList
|
||||
|
||||
generateBoardList: (text) ->
|
||||
unless list = $ '#custom-board-list', Header.nav
|
||||
# init'd with the custom board list disabled.
|
||||
return
|
||||
list = $ '#custom-board-list', Header.bar
|
||||
$.rmAll list
|
||||
return unless text
|
||||
as = $$('#full-board-list a', Header.nav)[0...-2] # ignore the Settings and Home links
|
||||
as = $$('#full-board-list a', Header.bar)[0...-2] # ignore the Settings and Home links
|
||||
nodes = text.match(/[\w@]+(-(all|title|replace|full|index|catalog|text:"[^"]+"))*|[^\w@]+/g).map (t) ->
|
||||
if /^[^\w@]/.test t
|
||||
return $.tn t
|
||||
@ -159,46 +156,51 @@ Header =
|
||||
$.add list, nodes
|
||||
|
||||
toggleBoardList: ->
|
||||
{nav} = Header
|
||||
custom = $ '#custom-board-list', nav
|
||||
full = $ '#full-board-list', nav
|
||||
{bar} = Header
|
||||
custom = $ '#custom-board-list', bar
|
||||
full = $ '#full-board-list', bar
|
||||
showBoardList = !full.hidden
|
||||
custom.hidden = !showBoardList
|
||||
full.hidden = showBoardList
|
||||
|
||||
setBarPosition: ->
|
||||
setBarPosition: (bottom) ->
|
||||
Header.barPositionToggler.checked = bottom
|
||||
if bottom
|
||||
$.rmClass doc, 'top'
|
||||
$.addClass doc, 'bottom'
|
||||
else
|
||||
$.rmClass doc, 'bottom'
|
||||
$.addClass doc, 'top'
|
||||
|
||||
toggleBarPosition: ->
|
||||
$.event 'CloseMenu'
|
||||
|
||||
Header.changeBarPosition @textContent
|
||||
Header.setBarPosition @checked
|
||||
|
||||
Conf['Boards Navigation'] = @textContent
|
||||
$.set 'Boards Navigation', @textContent
|
||||
Conf['Bottom Header'] = @checked
|
||||
$.set 'Bottom Header', @checked
|
||||
|
||||
changeBarPosition: (setting) ->
|
||||
$.rmClass doc, 'top'
|
||||
$.rmClass doc, 'fixed'
|
||||
$.rmClass doc, 'bottom'
|
||||
$.rmClass Header.nav, 'dialog'
|
||||
switch setting
|
||||
when 'Sticky top'
|
||||
$.addClass doc, 'top'
|
||||
$.addClass doc, 'fixed'
|
||||
$.addClass Header.nav, 'dialog'
|
||||
when 'Sticky bottom'
|
||||
$.addClass doc, 'fixed'
|
||||
$.addClass doc, 'bottom'
|
||||
$.addClass Header.nav, 'dialog'
|
||||
when 'Top'
|
||||
$.addClass doc, 'top'
|
||||
setBarFixed: (fixed) ->
|
||||
Header.barFixedToggler.checked = fixed
|
||||
if fixed
|
||||
$.addClass doc, 'fixed'
|
||||
$.addClass Header.bar, 'dialog'
|
||||
else
|
||||
$.rmClass doc, 'fixed'
|
||||
$.rmClass Header.bar, 'dialog'
|
||||
|
||||
toggleBarFixed: ->
|
||||
$.event 'CloseMenu'
|
||||
|
||||
Header.setBarFixed @checked
|
||||
|
||||
Conf['Fixed Header'] = @checked
|
||||
$.set 'Fixed Header', @checked
|
||||
|
||||
setBarVisibility: (hide) ->
|
||||
Header.headerToggler.checked = hide
|
||||
$.event 'CloseMenu'
|
||||
(if hide then $.addClass else $.rmClass) Header.nav, 'autohide'
|
||||
|
||||
setFooterVisibility: (hide) ->
|
||||
Header.footerToggler.firstElementChild.checked = hide
|
||||
Header.footer.hidden = hide
|
||||
(if hide then $.addClass else $.rmClass) Header.bar, 'autohide'
|
||||
|
||||
toggleBarVisibility: (e) ->
|
||||
return if e.type is 'mousedown' and e.button isnt 0 # not LMB
|
||||
@ -215,20 +217,43 @@ Header =
|
||||
'The header bar will remain visible.'
|
||||
new Notification 'info', message, 2
|
||||
|
||||
setFooterVisibility: (hide) ->
|
||||
Header.footerToggler.checked = hide
|
||||
Header.footer.hidden = hide
|
||||
|
||||
toggleFooterVisibility: ->
|
||||
$.event 'CloseMenu'
|
||||
hide = if @nodeName is 'INPUT'
|
||||
@checked
|
||||
else
|
||||
!Header.footer.hidden
|
||||
!!Header.footer.hidden
|
||||
Header.setFooterVisibility hide
|
||||
$.set 'Footer auto-hide', hide
|
||||
$.set 'Bottom Board List', hide
|
||||
message = if hide
|
||||
'The bottom navigation will now be hidden.'
|
||||
else
|
||||
'The bottom navigation will remain visible.'
|
||||
new Notification 'info', message, 2
|
||||
|
||||
setCustomNav: (show) ->
|
||||
Header.customNavToggler.checked = show
|
||||
cust = $ '#custom-board-list', Header.bar
|
||||
full = $ '#full-board-list', Header.bar
|
||||
btn = $ '.hide-board-list-button', full
|
||||
[cust.hidden, full.hidden, btn.hidden] = if show
|
||||
[false, true, false]
|
||||
else
|
||||
[true, false, true]
|
||||
|
||||
toggleCustomNav: ->
|
||||
$.cb.checked.call @
|
||||
Header.setCustomNav @checked
|
||||
|
||||
editCustomNav: ->
|
||||
Settings.open 'Rice'
|
||||
settings = $.id 'fourchanx-settings'
|
||||
$('input[name=boardnav]', settings).focus()
|
||||
|
||||
hashScroll: ->
|
||||
return unless (hash = @location.hash) and post = $.id hash[1..]
|
||||
return if (Get.postFromRoot post).isHidden
|
||||
@ -236,7 +261,7 @@ Header =
|
||||
|
||||
scrollToPost: (post) ->
|
||||
{top} = post.getBoundingClientRect()
|
||||
if Conf['Boards Navigation'] is 'Sticky top'
|
||||
if Conf['Fixed Header'] and not Conf['Bottom Header']
|
||||
headRect = Header.bar.getBoundingClientRect()
|
||||
top += - headRect.top - headRect.height
|
||||
(if $.engine is 'webkit' then d.body else doc).scrollTop += top
|
||||
|
||||
@ -263,7 +263,7 @@ QR =
|
||||
elapsed = Math.floor (now - start) / $.SECOND
|
||||
if elapsed >= 0 # clock changed since then?
|
||||
seconds = Math.max seconds, types[type] - elapsed
|
||||
if hasFile and upSpd
|
||||
if Conf['Cooldown Prediction'] and hasFile and upSpd
|
||||
seconds -= Math.floor post.file.size / upSpd * upSpdAccuracy
|
||||
seconds = Math.max seconds, 0
|
||||
unless start <= now <= cooldown.timeout
|
||||
|
||||
@ -153,7 +153,7 @@ class Post
|
||||
unless strong = $ 'strong.warning', @nodes.info
|
||||
strong = $.el 'strong',
|
||||
className: 'warning'
|
||||
textContent: '[Deleted]'
|
||||
textContent: if @isReply then '[Deleted]' else '[Dead]'
|
||||
$.after $('input', @nodes.info), strong
|
||||
strong.textContent = if file then '[File deleted]' else '[Deleted]'
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user