Merge branch 'master' into v1.12

This commit is contained in:
ccd0 2016-06-08 22:19:51 -07:00
commit ac1cb8a50e
39 changed files with 856 additions and 565 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ node_modules/
/.events
/.events2
/dist/
/builds/*.gz

View File

@ -2,8 +2,49 @@
Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0).
### v1.11.35
**v1.11.35.1** *(2016-06-07)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.35.1/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.35.1/builds/4chan-X-noupdate.crx "Chromium version")]
- Merge v1.11.34.10: Fix blocking of CloudFlare scripts.
**v1.11.35.0** *(2016-06-05)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.35.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.35.0/builds/4chan-X-noupdate.crx "Chromium version")]
- Based on v1.11.34.9.
- Prefix the `gecko`, `blink`, `webkit`, and `edge` classes added to the document depending on the detected browser engine with `ua-`. The old versions are still available for now, but will be removed in the near future.
- Add https://whatanime.ga/ to the Sauce list.
- Various minor bugfixes.
### v1.11.34
**v1.11.34.10** *(2016-06-07)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.10/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.10/builds/4chan-X-noupdate.crx "Chromium version")]
- Fix blocking of CloudFlare scripts.
**v1.11.34.9** *(2016-06-03)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.9/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.9/builds/4chan-X-noupdate.crx "Chromium version")]
- Fix loading icon getting stuck on in Firefox.
**v1.11.34.8** *(2016-06-03)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.8/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.8/builds/4chan-X-noupdate.crx "Chromium version")]
- Replace malicious ad blacklist with a Javascript whitelist, which can be configured on the `Advanced` settings tab.
**v1.11.34.7** *(2016-05-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.7/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.7/builds/4chan-X-noupdate.crx "Chromium version")]
- Merge v1.11.33.7: Fix blinking in older browsers.
- Merge v1.11.33.7: Allow 4chan's blinking animations to work.
**v1.11.34.6** *(2016-05-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.6/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.6/builds/4chan-X-noupdate.crx "Chromium version")]
- Merge v1.11.33.6: Quick fix for blinking.
**v1.11.34.5** *(2016-05-19)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.5/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.5/builds/4chan-X-noupdate.crx "Chromium version")]
- Merge v1.11.33.5: Update ad server blacklist.
- Change link on report form to 4chan IRC.
**v1.11.34.4** *(2016-05-18)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.4/builds/4chan-X-noupdate.crx "Chromium version")]
- Add search by flag to archive link menu.
**v1.11.34.3** *(2016-05-18)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.3/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.3/builds/4chan-X-noupdate.crx "Chromium version")]
- Improve handling of errors due to interaction of 4chan X with ad blockers and NoScript.
**v1.11.34.2** *(2016-05-17)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.2/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.2/builds/4chan-X-noupdate.crx "Chromium version")]
- Approximately sync replaced WebM thumbnails with hover preview.
- Change default archive list update URL to https://mayhemydg.github.io/archives.json/archives.json.
**v1.11.34.1** *(2016-05-17)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.1/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.34.1/builds/4chan-X-noupdate.crx "Chromium version")]
- Fix some download button / menu item bugs.
@ -23,6 +64,16 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's wor
### v1.11.33
**v1.11.33.7** *(2016-05-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.7/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.7/builds/4chan-X-noupdate.crx "Chromium version")]
- Fix blinking in older browsers.
- Allow 4chan's blinking animations to work.
**v1.11.33.6** *(2016-05-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.6/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.6/builds/4chan-X-noupdate.crx "Chromium version")]
- Quick fix for blinking.
**v1.11.33.5** *(2016-05-19)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.5/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.5/builds/4chan-X-noupdate.crx "Chromium version")]
- Update ad server blacklist.
**v1.11.33.4** *(2016-05-17)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.33.4/builds/4chan-X-noupdate.crx "Chromium version")]
- Archive list: waruso.org is back; also temporarily add fgts.jp (still down) as last option in list.

View File

@ -1,7 +1,5 @@
## Reporting bugs
**If you have recently started seeing errors about "File Info Formatting" crashing, check if you have the Chrome extension "Emoji Input by EmojiStuff.com", and if so, disable or uninstall it.**
Bug reports and feature requests for 4chan X are tracked at **https://github.com/ccd0/4chan-x/issues?q=is%3Aopen+sort%3Aupdated-desc**.
You can submit a bug report / feature request either via your Github account or the [anonymous report form](https://gitreports.com/issue/ccd0/4chan-x).
@ -9,7 +7,7 @@ You can submit a bug report / feature request either via your Github account or
If you're reporting a bug, the more detail you can give, the better. If I can't reproduce your bug, I probably won't be able to fix it. You can help by doing the following:
1. Include precise steps to reproduce the problem, with the expected and actual results.
2. Please mention any other extensions / scripts you are using. To check if a bug is due to a conflict with another extension, temporarily disable any other extensions and userscripts. If the bug goes away, turn them back on one by one until you find the one causing the problem.
2. **Please mention any other extensions / scripts you are using.** To check if a bug is due to a conflict with another extension, temporarily disable any other extensions and userscripts. If the bug goes away, turn them back on one by one until you find the one causing the problem.
3. Make sure your **browser**, **4chan X**, and (if applicable) **Greasemonkey** are up to date. Include the versions you're using in bug reports.
4. Test if the bug occurs with 4chan X disabled and using the native extension. If it does, it's likely a problem with 4chan or your browser rather than with 4chan X.
5. Open your console with Shift+Control+J (⇧⌘J on OS X Firefox, ⌘⌥J on OS X Chromium), and look for any error messages, especially ones that occur at the same time as the bug. Include these in your bug report. If you're using Firefox, be sure to check the browser console (Shift+Control+J), not the web console (Shift+Control+K) as errors may not show up in the latter.

View File

@ -15,7 +15,7 @@ else
endif
CP = $(call CAT,$<,$@)
npgoals := clean cleanrel cleanweb cleanfull withtests tag wrapped $(foreach i,1 2 3 4,bump$(i)) beta stable web update updatehard
npgoals := clean cleanrel cleanweb cleanfull withtests wrapped $(foreach i,1 2 3 4,bump$(i)) tag tagcommit beta stable web update updatehard
ifneq "$(filter $(npgoals),$(MAKECMDGOALS))" ""
.NOTPARALLEL :
endif
@ -302,27 +302,26 @@ withtests :
-$(MAKE)
echo false> .tests_enabled
ifneq "$(wildcard npm-shrinkwrap.json)" ""
tag : .events/CHANGELOG jshint release
git commit -am "Release $(meta_name) v$(version)."
git tag -a $(version) -m "$(meta_name) v$(version)."
endif
wrapped : src/meta/npm-shrinkwrap.json
$(call CAT,$<,npm-shrinkwrap.json)
npm install
$(foreach i,1 2 3 4,bump$(i)) :
node tools/bump.js $(subst bump,,$@)
$(MAKE) .events/CHANGELOG
tag :
$(MAKE) all
git add builds
$(MAKE) cleanrel
$(MAKE) wrapped
$(MAKE) all
git diff --quiet -- builds
$(MAKE) tag
$(MAKE) tagcommit
tagcommit :
git commit -am "Release $(meta_name) v$(version)."
git tag -a $(version) -m "$(meta_name) v$(version)."
beta : distready
git tag -af beta -m "$(meta_name) v$(version)."
@ -340,16 +339,18 @@ stable : distready
web : index.html distready
-git commit -am "Build web page."
cd dist && git merge --no-commit -s ours master
cd dist && git checkout master README.md index.html web.css img
cd dist && git checkout master README.md index.html web.css img .gitignore .gitattributes
cd dist && git commit -am "Update web page."
update :
$(RM) npm-shrinkwrap.json
npm install --save-dev $(shell node tools/unpinned.js)
npm install
npm shrinkwrap --dev
$(call CAT,npm-shrinkwrap.json,src/meta/npm-shrinkwrap.json)
updatehard :
$(RM) npm-shrinkwrap.json
npm install --save-dev $(shell node tools/unpinned.js latest)
npm install
npm shrinkwrap --dev

View File

@ -7,7 +7,7 @@ If you're looking for a maintained fork of OneeChan (a style script used in addi
https://github.com/Nebukazar/OneeChan.
## Please note
**Uninstalling**: 4chan X disables the native extension, so if you uninstall 4chan X, you'll need to re-enable it. To do this, click the `[Settings]` link in the top right corner and uncheck "`Disable the native extension`" in the panel that appears.
**Uninstalling**: 4chan X disables the native extension, so if you uninstall 4chan X, you'll need to re-enable it. To do this, click the `[Settings]` link in the top right corner, uncheck "`Disable the native extension`" in the panel that appears, and click the "`Save Settings`" button.
**Private browsing**: 4chan X does not yet support private browsing / incognito mode. Although it may work in this mode, browsing data recorded by 4chan X, such as your last read post in a thread and which posts are yours, will still need to be cleared manually by resetting your settings. To control what browsing data 4chan X records, use the `Remember Last Read Post` and `Mark Quotes of You` options in the settings panel.

Binary file not shown.

View File

@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X beta
// @version 1.11.34.1
// @version 1.11.35.1
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X
// @version 1.11.34.1
// @version 1.11.35.1
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
<updatecheck codebase='https://www.4chan-x.net/builds/4chan-X-beta.crx' version='1.11.34.1' />
<updatecheck codebase='https://www.4chan-x.net/builds/4chan-X-beta.crx' version='1.11.35.1' />
</app>
</gupdate>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
<updatecheck codebase='https://www.4chan-x.net/builds/4chan-X.crx' version='1.11.34.1' />
<updatecheck codebase='https://www.4chan-x.net/builds/4chan-X.crx' version='1.11.35.1' />
</app>
</gupdate>

View File

@ -22,7 +22,7 @@ Previously developed by <a href="https://github.com/aeosynth/4chan-x">aeosynth</
<p>If you're looking for a maintained fork of OneeChan (a style script used in addition to 4chan X), try
<a href="https://github.com/Nebukazar/OneeChan">https://github.com/Nebukazar/OneeChan</a>.</p>
<h2 id="please-note">Please note</h2>
<p><strong>Uninstalling</strong>: 4chan X disables the native extension, so if you uninstall 4chan X, you'll need to re-enable it. To do this, click the <code>[Settings]</code> link in the top right corner and uncheck &quot;<code>Disable the native extension</code>&quot; in the panel that appears.</p>
<p><strong>Uninstalling</strong>: 4chan X disables the native extension, so if you uninstall 4chan X, you'll need to re-enable it. To do this, click the <code>[Settings]</code> link in the top right corner, uncheck &quot;<code>Disable the native extension</code>&quot; in the panel that appears, and click the &quot;<code>Save Settings</code>&quot; button.</p>
<p><strong>Private browsing</strong>: 4chan X does not yet support private browsing / incognito mode. Although it may work in this mode, browsing data recorded by 4chan X, such as your last read post in a thread and which posts are yours, will still need to be cleared manually by resetting your settings. To control what browsing data 4chan X records, use the <code>Remember Last Read Post</code> and <code>Mark Quotes of You</code> options in the settings panel.</p>
<p><strong>HTTPS</strong>: 4chan X currently shares your settings and post history between the HTTP and HTTPS versions of 4chan. If you are concerned about protecting your privacy against a man-in-the-middle attack, you should disable 4chan X on the HTTP version of 4chan and/or install <a href="https://www.eff.org/https-everywhere">HTTPS Everywhere</a>.</p>
<h2 id="install">Install</h2>

View File

@ -49,17 +49,17 @@
}
},
"devDependencies": {
"coffee-script": "1.9.3",
"coffee-script": "=1.9.3",
"crx": "^3.0.3",
"esprima": "^2.7.2",
"font-awesome": "4.6.1",
"font-awesome": "=4.6.3",
"jshint": "^2.9.2",
"jszip": "^3.0.0",
"lodash.template": "^4.2.4",
"markdown-it": "^6.0.1",
"lodash.template": "^4.2.5",
"markdown-it": "^6.0.2",
"markdown-it-anchor": "^2.5.0",
"request": "^2.72.0",
"webstore-upload": "^0.0.7"
"webstore-upload": "0.0.7"
},
"repository": {
"type": "git",

View File

@ -23,6 +23,7 @@ Redirect =
for key in ['boards', 'files']
data[key] = [] unless data[key] instanceof Array
{uid, name, boards, files, software, withCredentials} = data
continue unless software in ['fuuka', 'foolfuuka']
archives[JSON.stringify(uid ? name)] = data
for boardID in boards
unless withCredentials
@ -50,8 +51,8 @@ Redirect =
urls.push url if url
load = (i) -> ->
fail = (action, msg) -> new Notice 'warning', "Error #{action} archive data from #{urls[i]}\n#{msg}", 20
return fail 'fetching', (if @status then "#{@status} #{@statusText}" else 'Connection Error') unless @status is 200
fail = (action, msg) -> new Notice 'warning', "Error #{action} archive data from\n#{urls[i]}\n#{msg}", 20
return fail 'fetching', (if @status then "Error #{@statusText} (#{@status})" else 'Connection Error') unless @status is 200
try
response = JSON.parse @response
catch err

View File

@ -23,8 +23,10 @@ Filter =
boards = if boards is 'global' then null else boards.split(',')
# boards to exclude from an otherwise global rule
if boards is null
excludes = filter.match(/exclude:([^;]+)/)?[1].toLowerCase().split(',') or null
excludes = if boards is null
filter.match(/exclude:([^;]+)/)?[1].toLowerCase().split(',') or null
else
null
if key in ['uniqueID', 'MD5']
# MD5 filter will use strings instead of regular expressions.

View File

@ -515,7 +515,7 @@ Index =
return
if req.status not in [200, 304]
err = "Index refresh failed. Error #{req.statusText} (#{req.status})"
err = "Index refresh failed. #{if req.status then "Error #{req.statusText} (#{req.status})" else 'Connection Error'}"
if notice
notice.setType 'warning'
notice.el.lastElementChild.textContent = err

View File

@ -28,8 +28,8 @@ Settings =
settings.disableAll = true
localStorage.setItem '4chan-settings', JSON.stringify settings
else
$.onExists doc, 'body', ->
$.global -> window.Config.disableAll = true
$.global ->
Object.defineProperty window, 'Config', {value: {disableAll: true}}
open: (openSection) ->
return if Settings.overlay
@ -373,6 +373,8 @@ Settings =
'#https://foolz.fireden.net/_/search/image/%sMD5/'
'#//www.gif-explode.com/%URL;types:gif'
]
if compareString < '00001.00011.00035.00000'
addSauces ['https://whatanime.ga/?auto&url=%IMG;text:wait']
changes
loadSettings: (data, cb) ->
@ -436,7 +438,7 @@ Settings =
$.id('lastarchivecheck').textContent = 'never'
items = {}
for name in ['archiveLists', 'archiveAutoUpdate', 'captchaLanguage', 'boardnav', 'time', 'backlink', 'fileInfo', 'QR.personas', 'favicon', 'usercss', 'customCooldown']
for name in ['archiveLists', 'archiveAutoUpdate', 'captchaLanguage', 'boardnav', 'time', 'backlink', 'fileInfo', 'QR.personas', 'favicon', 'usercss', 'customCooldown', 'jsWhitelist']
items[name] = Conf[name]
input = inputs[name]
event = if name in ['archiveLists', 'archiveAutoUpdate', 'QR.personas', 'favicon', 'usercss'] then 'change' else 'input'
@ -498,6 +500,7 @@ Settings =
archBoards = {}
for {uid, name, boards, files, software, withCredentials} in Conf['archives']
continue unless software in ['fuuka', 'foolfuuka']
for boardID in boards
o = archBoards[boardID] or=
thread: [[], []]

View File

@ -140,3 +140,9 @@
<button id="apply-css">Apply CSS</button>
<textarea name="usercss" class="field" spellcheck="false"></textarea>
</fieldset>
<fieldset>
<legend>Javascript Whitelist</legend>
<div>Sources from which Javascript is allowed to be loaded by <a href="http://content-security-policy.com/#source_list" target="_blank">Content Security Policy</a>.</div>
<textarea name="jsWhitelist" class="field" spellcheck="false"></textarea>
</fieldset>

View File

@ -40,7 +40,9 @@ ImageHover =
el.loop = true
el.controls = false
Volume.setup el
el.play() if Conf['Autoplay']
if Conf['Autoplay']
el.play()
@currentTime = el.currentTime if @nodeName is 'VIDEO'
[width, height] = (+x for x in file.dimensions.split 'x')
{left, right} = @getBoundingClientRect()
maxWidth = Math.max left, doc.clientWidth - right

View File

@ -310,7 +310,7 @@ Embedding =
loop: true
,
key: 'Pastebin'
regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w\.]+\?i\=)?(\w+)/
regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/
el: (a) ->
div = $.el 'iframe',
src: "//pastebin.com/embed_iframe.php?i=#{a.dataset.uid}"

View File

@ -18,6 +18,7 @@ ArchiveLink =
['Tripcode', 'tripcode']
['Capcode', 'capcode']
['Subject', 'subject']
['Flag', 'country']
['Filename', 'filename']
['Image MD5', 'MD5']
]
@ -37,7 +38,10 @@ ArchiveLink =
true
else
(post) ->
value = Filter[type] post
value = if type is 'country'
post.info.flagCode
else
Filter[type] post
# We want to parse the exact same stuff as the filter does already.
return false unless value
el.href = Redirect.to 'search',

View File

@ -21,8 +21,8 @@ Report =
$.after passAd, [
$.tn '] ['
$.el 'a',
href: 'mailto:4chanpass@4chan.org?subject=4chan%20Pass%20-%20Purchase%20Support'
textContent: 'Email 4chan'
href: 'irc://irc.rizon.net/4chan'
textContent: '4chan IRC'
target: '_blank'
tabIndex: -1
]

View File

@ -50,7 +50,7 @@ ReplyPruning =
ReplyPruning.active = @checked
showIfHidden: (id) ->
if ReplyPruning.container?.getElementById id
if ReplyPruning.container and $("##{id}", ReplyPruning.container)
ReplyPruning.inputs.enabled.checked = false
$.event 'change', null, ReplyPruning.inputs.enabled

View File

@ -2,7 +2,11 @@ ThreadUpdater =
init: ->
return if g.VIEW isnt 'thread' or !Conf['Thread Updater']
@audio = $.el 'audio', src: ThreadUpdater.beep
# Chromium won't play audio created in an inactive tab until the tab has been focused, so set it up now.
# XXX Sometimes the loading stalls in Firefox, esp. when opening in private browsing window followed by normal window.
# Don't let it keep the loading icon on indefinitely.
@audio = $.el 'audio'
@audio.src = @beep unless $.engine is 'gecko'
if Conf['Updater and Stats in Header']
@dialog = sc = $.el 'span',
@ -90,6 +94,7 @@ ThreadUpdater =
playBeep: ->
{audio} = ThreadUpdater
audio.src or= ThreadUpdater.beep
if audio.paused
audio.play()
else
@ -162,7 +167,7 @@ ThreadUpdater =
ThreadUpdater.set 'status', ''
ThreadUpdater.setInterval()
unless req.status
ThreadUpdater.set 'status', 'Connection Failed', 'warning'
ThreadUpdater.set 'status', 'Connection Error', 'warning'
else if req.status isnt 304
ThreadUpdater.set 'status', "#{req.statusText} (#{req.status})", 'warning'

View File

@ -48,7 +48,7 @@ class Fetcher
return
{status} = req
unless status in [200, 304]
unless status is 200
# The thread can die by the time we check a quote.
return if @archivedPost()

View File

@ -28,6 +28,7 @@ class Post
tripcode: @nodes.tripcode?.textContent
uniqueID: @nodes.uniqueID?.firstElementChild.textContent
capcode: @nodes.capcode?.textContent.replace '## ', ''
flagCode: @nodes.flag?.className.match(/flag-(\w+)/)?[1].toUpperCase()
flag: @nodes.flag?.title
date: if @nodes.date then new Date(@nodes.date.dataset.utc * 1000)
@ -145,7 +146,7 @@ class Post
match = quotelink.href.match ///
^https?://boards\.4chan\.org/+
([^/]+) # boardID
/+(?:res|thread)/+\d+(?:/[^#]*)?#p
/+(?:res|thread)/+\d+(?:[/?][^#]*)?#p
(\d+) # postID
$
///

View File

@ -710,6 +710,7 @@ Config =
# Specialized reverse image search:
//iqdb.org/?url=%IMG
https://whatanime.ga/?auto&url=%IMG;text:wait
#//3d.iqdb.org/?url=%IMG
#//saucenao.com/search.php?url=%IMG
@ -752,7 +753,7 @@ Config =
'Custom Board Navigation': true
archives:
archiveLists: 'https://4chan-x.just-believe.in/json/archives.json'
archiveLists: 'https://mayhemydg.github.io/archives.json/archives.json'
lastarchivecheck: 0
archiveAutoUpdate: true
@ -782,6 +783,17 @@ Config =
"""
sjisPreview: false
jsWhitelist: '''
http://s.4cdn.org
https://s.4cdn.org
http://www.google.com
https://www.google.com
https://www.gstatic.com
'self'
'unsafe-inline'
'unsafe-eval'
'''
captchaLanguage: ''
time: '%m/%d/%y(%a)%H:%M:%S'

View File

@ -115,6 +115,11 @@ body > div[style*=" top: -10000px;"] {
visibility: hidden !important;
}
:root.blink {
-webkit-animation: none;
animation: none;
}
/* Ads */
:root:not(.ads-loaded) .ad-cnt,
:root:not(.ads-loaded) .ad-plea,
@ -1072,7 +1077,7 @@ span.hide-announcement {
:root.fit-width .full-image {
max-width: 100%;
}
:root.gecko.fit-width .full-image {
:root.ua-gecko.fit-width .full-image {
width: 100%;
}
.fileThumb > .warning {
@ -1398,10 +1403,10 @@ input.field.tripped:not(:hover):not(:focus) {
width: 304px;
}
/* scrollable with scroll bar hidden; prevents scroll on space press */
:root.blink #qr .captcha-container > div {
:root.ua-blink #qr .captcha-container > div {
overflow: hidden;
}
:root.blink #qr .captcha-container > div > div:first-of-type {
:root.ua-blink #qr .captcha-container > div > div:first-of-type {
overflow-y: scroll;
overflow-x: hidden;
padding-right: 15px;
@ -1722,9 +1727,6 @@ a:only-of-type > .remove {
display: -webkit-flex;
display: flex;
}
:root.webkit .textarea {
margin-bottom: -2px;
}
#char-count {
color: #000;
background: hsla(0, 0%, 100%, .5);

View File

@ -13,20 +13,9 @@ Main =
$.ready -> Captcha.fixes.init()
return
# Disrupt loading of ads from malicious/irresponsible providers.
$.global ->
nuke = (obj, prop) ->
try
Object.defineProperty obj, prop,
configurable: false
get: -> throw new Error()
set: -> throw new Error()
for prop in ['atOptions', 'adsterra_key', 'EpmadsConfig', 'epmads_key', 'EpomConfig', 'epom_key', 'exoDocumentProtocol']
nuke window, prop
return
$.on window, 'beforescriptexecute', (e) ->
host = e.target.src.split('/')[2]?.match(/[^.]+\.[^.]+$/)?[0]
e.preventDefault() if host in ['bnhtml.com', 'ecpmrocks.com', 'advertisation.com', 'exoclick.com']
# Don't run inside ad iframes.
try
return if window.frameElement and window.frameElement.src is ''
# Detect multiple copies of 4chan X
$.on d, '4chanXInitFinished', ->
@ -61,11 +50,35 @@ Main =
Conf['JSON Navigation'] = true
Conf['Oekaki Links'] = true
# Pseudo-enforce default whitelist while configuration loads
if $.platform is 'crx' then $.global ->
{whitelist} = document.currentScript.dataset
whitelist = whitelist.split('\n').filter (x) -> x[0] isnt "'"
whitelist.push "#{location.protocol}//#{location.host}"
oldFun = {}
for key in ['createElement', 'write']
oldFun[key] = document[key]
document[key] = do (key) -> (arg) ->
s = document.currentScript
if s and s.src and whitelist.indexOf(s.src.split('/')[..2].join('/')) < 0
throw Error()
oldFun[key].call document, arg
document.addEventListener 'csp-ready', ->
document[key] = oldFun[key] for key of oldFun
, false
,
whitelist: Conf['jsWhitelist']
# Get saved values as items
items = {}
items[key] = undefined for key of Conf
items['previousversion'] = undefined
$.get items, (items) ->
($.getSync or $.get) items, (items) ->
# Enforce JS whitelist
jsWhitelist = items['jsWhitelist'] ? Conf['jsWhitelist']
$.addCSP "script-src #{jsWhitelist.replace(/[\s;]+/g, ' ')}"
$.event 'csp-ready' if $.platform is 'crx'
$.asap docSet, ->
# Don't hide the local storage warning behind a settings panel.
@ -183,7 +196,7 @@ Main =
$('link[href*=mobile]', d.head)?.disabled = true
$.addClass doc, 'fourchan-x', 'seaweedchan'
$.addClass doc, if g.VIEW is 'thread' then 'thread-view' else g.VIEW
$.addClass doc, $.engine if $.engine
$.addClass doc, "ua-#{$.engine}", $.engine if $.engine
$.onExists doc, '.ad-cnt', (ad) -> $.onExists ad, 'img', -> $.addClass doc, 'ads-loaded'
$.addClass doc, 'autohiding-scrollbar' if Conf['Autohiding Scrollbar']
$.ready ->
@ -335,6 +348,11 @@ Main =
softTask()
handleErrors: (errors) ->
# Detect conflicts with 4chan X v2
if d.body and $.hasClass(d.body, 'fourchan_x') and not $.hasClass(doc, 'tainted')
new Notice 'error', 'Error: Multiple copies of 4chan X are enabled.'
$.addClass doc, 'tainted'
unless errors instanceof Array
error = errors
else if errors.length is 1

View File

@ -22,9 +22,9 @@
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.7.tgz"
},
"asap": {
"version": "2.0.3",
"version": "2.0.4",
"from": "asap@>=2.0.3 <2.1.0",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.3.tgz"
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.4.tgz"
},
"asn1": {
"version": "0.2.3",
@ -47,21 +47,14 @@
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
},
"aws4": {
"version": "1.3.2",
"version": "1.4.1",
"from": "aws4@>=1.2.1 <2.0.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.3.2.tgz",
"dependencies": {
"lru-cache": {
"version": "4.0.1",
"from": "lru-cache@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz"
}
}
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz"
},
"balanced-match": {
"version": "0.3.0",
"from": "balanced-match@>=0.3.0 <0.4.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz"
"version": "0.4.1",
"from": "balanced-match@>=0.4.1 <0.5.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.1.tgz"
},
"bl": {
"version": "1.1.2",
@ -91,9 +84,9 @@
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz"
},
"brace-expansion": {
"version": "1.1.3",
"version": "1.1.4",
"from": "brace-expansion@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz"
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.4.tgz"
},
"buffer-crc32": {
"version": "0.2.5",
@ -161,9 +154,9 @@
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
},
"dashdash": {
"version": "1.13.0",
"from": "dashdash@>=1.10.1 <2.0.0",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.13.0.tgz",
"version": "1.13.1",
"from": "dashdash@>=1.12.0 <2.0.0",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.13.1.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
@ -282,9 +275,9 @@
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz"
},
"font-awesome": {
"version": "4.6.1",
"from": "font-awesome@4.6.1",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.6.1.tgz"
"version": "4.6.3",
"from": "font-awesome@latest",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.6.3.tgz"
},
"forever-agent": {
"version": "0.6.1",
@ -306,6 +299,18 @@
"from": "generate-object-property@>=1.1.0 <2.0.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz"
},
"getpass": {
"version": "0.1.6",
"from": "getpass@>=0.1.1 <0.2.0",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"glob": {
"version": "3.2.11",
"from": "glob@>=3.2.1 <3.3.0",
@ -366,9 +371,9 @@
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz"
},
"inflight": {
"version": "1.0.4",
"version": "1.0.5",
"from": "inflight@>=1.0.4 <2.0.0",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz"
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz"
},
"inherits": {
"version": "2.0.1",
@ -495,9 +500,9 @@
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz"
},
"lodash.assigninwith": {
"version": "4.0.6",
"version": "4.0.7",
"from": "lodash.assigninwith@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash.assigninwith/-/lodash.assigninwith-4.0.6.tgz"
"resolved": "https://registry.npmjs.org/lodash.assigninwith/-/lodash.assigninwith-4.0.7.tgz"
},
"lodash.escape": {
"version": "4.0.0",
@ -505,24 +510,24 @@
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.0.tgz"
},
"lodash.keys": {
"version": "4.0.6",
"version": "4.0.7",
"from": "lodash.keys@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.0.6.tgz"
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.0.7.tgz"
},
"lodash.keysin": {
"version": "4.1.3",
"version": "4.1.4",
"from": "lodash.keysin@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-4.1.3.tgz"
"resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-4.1.4.tgz"
},
"lodash.rest": {
"version": "4.0.2",
"version": "4.0.3",
"from": "lodash.rest@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.2.tgz"
"resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.3.tgz"
},
"lodash.template": {
"version": "4.2.4",
"from": "lodash.template@>=4.2.4 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.2.4.tgz"
"version": "4.2.5",
"from": "lodash.template@latest",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.2.5.tgz"
},
"lodash.templatesettings": {
"version": "4.0.1",
@ -530,9 +535,9 @@
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.0.1.tgz"
},
"lodash.tostring": {
"version": "4.1.2",
"version": "4.1.3",
"from": "lodash.tostring@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.2.tgz"
"resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.3.tgz"
},
"lru-cache": {
"version": "2.7.3",
@ -540,9 +545,9 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
},
"markdown-it": {
"version": "6.0.1",
"version": "6.0.2",
"from": "markdown-it@latest",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.0.1.tgz",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.0.2.tgz",
"dependencies": {
"entities": {
"version": "1.1.1",
@ -562,14 +567,14 @@
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz"
},
"mime-db": {
"version": "1.22.0",
"from": "mime-db@>=1.22.0 <1.23.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.22.0.tgz"
"version": "1.23.0",
"from": "mime-db@>=1.23.0 <1.24.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz"
},
"mime-types": {
"version": "2.1.10",
"version": "2.1.11",
"from": "mime-types@>=2.1.7 <2.2.0",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.10.tgz"
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz"
},
"minimatch": {
"version": "0.2.14",
@ -599,9 +604,9 @@
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
},
"oauth-sign": {
"version": "0.8.1",
"version": "0.8.2",
"from": "oauth-sign@>=0.8.1 <0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.1.tgz"
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
},
"once": {
"version": "1.3.3",
@ -639,14 +644,9 @@
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
},
"process-nextick-args": {
"version": "1.0.6",
"version": "1.0.7",
"from": "process-nextick-args@>=1.0.6 <1.1.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.6.tgz"
},
"pseudomap": {
"version": "1.0.2",
"from": "pseudomap@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz"
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz"
},
"q": {
"version": "1.4.1",
@ -674,9 +674,9 @@
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-2.0.1.tgz",
"dependencies": {
"lodash": {
"version": "4.11.1",
"version": "4.13.1",
"from": "lodash@>=4.5.0 <5.0.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.11.1.tgz"
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz"
}
}
},
@ -706,9 +706,16 @@
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
},
"sshpk": {
"version": "1.7.4",
"version": "1.8.3",
"from": "sshpk@>=1.7.0 <2.0.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.7.4.tgz"
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.8.3.tgz",
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"from": "assert-plus@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
}
}
},
"string": {
"version": "3.3.1",
@ -751,14 +758,14 @@
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz"
},
"tunnel-agent": {
"version": "0.4.2",
"version": "0.4.3",
"from": "tunnel-agent@>=0.4.1 <0.5.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.2.tgz"
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz"
},
"tweetnacl": {
"version": "0.14.3",
"from": "tweetnacl@>=0.13.0 <1.0.0",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz"
"version": "0.13.3",
"from": "tweetnacl@>=0.13.0 <0.14.0",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz"
},
"uc.micro": {
"version": "1.0.0",
@ -793,9 +800,9 @@
}
},
"wrappy": {
"version": "1.0.1",
"version": "1.0.2",
"from": "wrappy@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
},
"wrench": {
"version": "1.5.9",
@ -807,11 +814,6 @@
"from": "xtend@>=4.0.0 <5.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
},
"yallist": {
"version": "2.0.0",
"from": "yallist@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz"
},
"zip-stream": {
"version": "0.3.7",
"from": "zip-stream@>=0.3.0 <0.4.0",

View File

@ -43,18 +43,6 @@ $.ajax = do ->
# This saves a lot of bandwidth and CPU time for both the users and the servers.
lastModified = {}
blockedURLs = {}
blockedError = (url) ->
return if blockedURLs[url]
blockedURLs[url] = true
message = $.el 'div',
<%= html(
meta.name + ' was blocked from loading the following URL:<br><span></span><br>' +
'[<a href="' + meta.faq + '#why-was-' + name.toLowerCase() + '-blocked-from-loading-a-url" target="_blank">More info</a>]'
) %>
$('span', message).textContent = (if /^\/\//.test url then location.protocol else '') + url
new Notice 'warning', message, 30, -> delete blockedURLs[url]
(url, options={}, extra={}) ->
{type, whenModified, upCallbacks, form} = extra
# XXX https://forums.lanik.us/viewtopic.php?f=64&t=24173&p=78310
@ -63,21 +51,22 @@ $.ajax = do ->
type or= form and 'post' or 'get'
try
r.open type, url, true
if whenModified
r.setRequestHeader 'If-Modified-Since', lastModified[whenModified][url] if lastModified[whenModified]?[url]?
$.on r, 'load', -> (lastModified[whenModified] or= {})[url] = r.getResponseHeader 'Last-Modified'
if /\.json$/.test url
options.responseType ?= 'json'
$.extend r, options
$.extend r.upload, upCallbacks
# connection error or content blocker
$.on r, 'error', -> c.error "4chan X failed to load: #{url}" unless r.status
r.send form
catch err
# XXX Some content blockers in Firefox (e.g. Adblock Plus) throw an exception here instead of dispatching an error event.
blockedError url
# XXX Some content blockers in Firefox (e.g. Adblock Plus and NoScript) throw an exception instead of simulating a connection error.
throw err unless err.result is 0x805e0006
for event in ['error', 'loadend']
r["on#{event}"] = options["on#{event}"]
$.queueTask $.event, event, null, r
return
if whenModified
r.setRequestHeader 'If-Modified-Since', lastModified[whenModified][url] if lastModified[whenModified]?[url]?
$.on r, 'load', -> (lastModified[whenModified] or= {})[url] = r.getResponseHeader 'Last-Modified'
if /\.json$/.test url
options.responseType ?= 'json'
$.extend r, options
$.extend r.upload, upCallbacks
r.send form
r
do ->
@ -138,6 +127,18 @@ $.addStyle = (css, id, test='head') ->
$.add d.head, style
style
$.addCSP = (policy) ->
meta = $.el 'meta',
httpEquiv: 'Content-Security-Policy'
content: policy
if d.head
$.add d.head, meta
$.rm meta
else
head = $.add (doc or d), $.el('head')
$.add head, meta
$.rm head
$.x = (path, root) ->
root or= d.body
# XPathResult.ANY_UNORDERED_NODE_TYPE === 8
@ -296,15 +297,16 @@ $.queueTask = do ->
taskQueue.push arguments
setTimeout execTask, 0
$.globalEval = (code) ->
$.globalEval = (code, data) ->
script = $.el 'script',
textContent: code
$.extend script.dataset, data if data
$.add (d.head or doc), script
$.rm script
$.global = (fn) ->
$.global = (fn, data) ->
if doc
$.globalEval "(#{fn})();"
$.globalEval "(#{fn})();", data
else
# XXX dwb
fn()
@ -557,11 +559,12 @@ $.get = (key, val, cb) ->
else
items = key
cb = val
$.queueTask ->
for key of items
if val = $.getValue g.NAMESPACE + key
items[key] = JSON.parse val
cb items
$.queueTask $.getSync, items, cb
$.getSync = (items, cb) ->
for key of items when (val2 = $.getValue g.NAMESPACE + key)
items[key] = JSON.parse val2
cb items
$.set = (keys, val, cb) ->
if typeof keys is 'string'

View File

@ -4,7 +4,7 @@ var pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
console.log(
Object.keys(pkg.devDependencies).filter(
name => /^\^/.test(pkg.devDependencies[name])
name => !/^=/.test(pkg.devDependencies[name])
).map(
name => `${name}@${process.argv[2] || pkg.devDependencies[name]}`
).join(' ')

View File

@ -1,4 +1,5 @@
var fs = require('fs');
var child_process = require('child_process');
var pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
var v = JSON.parse(fs.readFileSync('version.json', 'utf8'));
@ -29,6 +30,7 @@ var prevVersion = changelog.substr(breakPos).match(/\*\*v([\d\.]+)\*\*/)[1];
if (prevVersion.replace(/\.\d+$/, '') !== branch) {
line += `\n- Based on v${prevVersion}.`;
}
line += '\n- ' + child_process.execSync(`git log --pretty=format:%s ${prevVersion}..HEAD`).toString().replace(/\n/g, '\n- ');
fs.writeFileSync('CHANGELOG.md', `${changelog.substr(0, breakPos)}\n\n${line}${changelog.substr(breakPos)}`, 'utf8');
console.log(`Changelog updated for v${version}.`);

View File

@ -1,4 +1,4 @@
{
"version": "1.11.34.1",
"date": "2016-05-17T06:04:25.221Z"
"version": "1.11.35.1",
"date": "2016-06-07T17:54:32.135Z"
}