Merge pull request #1183 from MayhemYDG/opera

Drop Opera <15 support.
This commit is contained in:
Mayhem 2013-07-09 01:56:58 -07:00
commit 39aa9d3cb5
15 changed files with 65 additions and 207 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
builds/
node_modules/
tmp-crx/
tmp-userjs/
tmp-userscript/

View File

@ -11,9 +11,8 @@ Reporting bugs:
4. Your exported settings. If your settings contains sensible information (e.g. personas), edit the text file manually.
Open your console with:
- `Ctrl + Shift + J` on Chrome.
- `Ctrl + Shift + J` on Chrome and Opera.
- `Ctrl + Shift + K` on Firefox.
- `Ctrl + Shift + O` on Opera.
Respect these guidelines:
- Describe the issue clearly, put some effort into it. A one-liner isn't a good enough description.

View File

@ -56,15 +56,6 @@ module.exports = function(grunt) {
]
}
},
userjs: {
options: concatOptions,
src: [
'src/Meta/metadata.js',
'src/Meta/banner.js',
'tmp-<%= pkg.type %>/script.js'
],
dest: 'builds/<%= pkg.name %>.js'
},
userscript: {
options: concatOptions,
files: {
@ -102,7 +93,7 @@ module.exports = function(grunt) {
}
},
concurrent: {
build: ['build-crx', 'build-userjs', 'build-userscript']
build: ['build-crx', 'build-userscript']
},
bump: {
options: {
@ -161,7 +152,6 @@ module.exports = function(grunt) {
clean: {
builds: 'builds',
tmpcrx: 'tmp-crx',
tmpuserjs: 'tmp-userjs',
tmpuserscript: 'tmp-userscript'
}
});
@ -193,13 +183,6 @@ module.exports = function(grunt) {
'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',

View File

@ -278,10 +278,8 @@ a[href="javascript:;"] {
box-sizing: border-box;
box-shadow: 0 0 15px rgba(0, 0, 0, .15);
height: 600px;
min-height: 0;
max-height: 100%;
width: 900px;
min-width: 0;
max-width: 100%;
margin: auto;
padding: 3px;
@ -468,7 +466,8 @@ a.hide-announcement {
.deadlink {
text-decoration: none !important;
}
.backlink.deadlink:not(.forwardlink), .quotelink.deadlink:not(.forwardlink) {
.backlink.deadlink:not(.forwardlink),
.quotelink.deadlink:not(.forwardlink) {
text-decoration: underline !important;
}
.inlined {
@ -508,8 +507,6 @@ a.hide-announcement {
padding: 2px 2px 5px;
}
#qp img {
max-height: 300px;
max-width: 500px;
max-height: 80vh;
max-width: 50vw;
}
@ -541,8 +538,7 @@ a.hide-announcement {
:root.fit-width .full-image {
max-width: 100%;
}
:root.gecko.fit-width .full-image,
:root.presto.fit-width .full-image {
:root.gecko.fit-width .full-image {
width: 100%;
}
#ihover {
@ -616,9 +612,6 @@ a.hide-announcement {
color: #000;
background-color: #F7F7F7;
}
.presto #qr select {
height: 1em;
}
#qr .close {
padding: 0 3px;
}
@ -649,13 +642,15 @@ a.hide-announcement {
outline: none;
width: 30px;
}
#dump-button:hover, #dump-button:focus {
#dump-button:hover,
#dump-button:focus {
background: linear-gradient(#FFF, #DDD);
}
#dump-button:active, .dump #dump-button:not(:hover):not(:focus) {
#dump-button:active,
.dump #dump-button:not(:hover):not(:focus) {
background: linear-gradient(#CCC, #DDD);
}
.gecko #dump-button {
:root.gecko #dump-button {
padding: 0;
}
#qr:not(.dump) #dump-list-container {
@ -670,7 +665,10 @@ a.hide-announcement {
}
#dump-list {
counter-reset: qrpreviews;
top: 0; right: 0; bottom: 0; left: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
white-space: nowrap;
@ -696,8 +694,10 @@ a.hide-announcement {
box-sizing: border-box;
cursor: move;
display: inline-block;
height: 92px; width: 92px;
margin: 4px; padding: 2px;
height: 92px;
width: 92px;
margin: 4px;
padding: 2px;
opacity: .6;
outline: none;
overflow: hidden;
@ -707,7 +707,8 @@ a.hide-announcement {
vertical-align: top;
white-space: pre;
}
.qr-preview:hover, .qr-preview:focus {
.qr-preview:hover,
.qr-preview:focus {
opacity: .9;
color: #FFF !important;
}
@ -720,7 +721,8 @@ a.hide-announcement {
font-weight: 700;
text-shadow: 0 0 3px #000, 0 0 5px #000;
position: absolute;
top: 3px; right: 3px;
top: 3px;
right: 3px;
}
.qr-preview.drag {
border-color: red;
@ -740,7 +742,9 @@ a.hide-announcement {
}
.qr-preview > label {
background: rgba(0, 0, 0, .5);
right: 0; bottom: 0; left: 0;
right: 0;
bottom: 0;
left: 0;
position: absolute;
text-align: center;
}
@ -756,7 +760,8 @@ a.hide-announcement {
line-height: 1;
text-align: center;
position: absolute;
right: 0; bottom: 0;
right: 0;
bottom: 0;
z-index: 1;
}
#qr textarea {
@ -822,7 +827,10 @@ a.hide-announcement {
}
#qr-filename {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@ -838,10 +846,6 @@ a.hide-announcement {
-webkit-order: 1;
order: 1;
}
#qr input[type='file'] {
position: absolute;
visibility: hidden;
}
/* Menu */
.menu-button {

View File

@ -31,7 +31,7 @@
<a id="qr-filerm" href="javascript:;" title="Remove file">×</a>
<input type="checkbox" id="qr-file-spoiler" title="Spoiler image">
</div>
<input type="file" multiple>
<input type="file" multiple hidden>
</form>
<datalist id="list-name"></datalist>
<datalist id="list-email"></datalist>

View File

@ -208,26 +208,19 @@ $.bytesToString = (size) ->
# Round to an integer otherwise.
Math.round size
"#{size} #{['B', 'KB', 'MB', 'GB'][unit]}"
$.item = (key, val) ->
item = {}
item[key] = val
item
$.syncing = {}
$.sync = do ->
<% if (type === 'crx') { %>
$.sync = do ->
chrome.storage.onChanged.addListener (changes) ->
for key of changes
if cb = $.syncing[key]
cb changes[key].newValue
return
(key, cb) -> $.syncing[key] = cb
<% } else { %>
$.on window, 'storage', (e) ->
if cb = $.syncing[e.key]
cb JSON.parse e.newValue
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
<% } %>
$.item = (key, val) ->
item = {}
item[key] = val
item
<% if (type === 'crx') { %>
$.localKeys = [
# filters
'name',
@ -300,52 +293,13 @@ $.set = do ->
else
$.extend items, key
set()
<% } else if (type === 'userjs') { %>
do ->
# http://www.opera.com/docs/userjs/specs/#scriptstorage
# http://www.opera.com/docs/userjs/using/#securepages
# The scriptStorage object is available only during
# the main User JavaScript thread, being therefore
# accessible only in the main body of the user script.
# To access the storage object later, keep a reference
# to the object.
{scriptStorage} = opera
$.delete = (keys) ->
unless keys instanceof Array
keys = [keys]
for key in keys
key = g.NAMESPACE + key
localStorage.removeItem key
delete scriptStorage[key]
return
$.get = (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
$.queueTask ->
for key of items
if val = scriptStorage[g.NAMESPACE + key]
items[key] = JSON.parse val
cb items
$.set = do ->
set = (key, val) ->
key = g.NAMESPACE + key
val = JSON.stringify val
if key of $.syncing
# for `storage` events
localStorage.setItem key, val
scriptStorage[key] = val
(keys, val) ->
if typeof keys is 'string'
set keys, val
return
for key, val of keys
set key, val
return
<% } else { %>
# http://wiki.greasespot.net/Main_Page
# http://wiki.greasespot.net/Main_Page
$.sync = do ->
$.on window, 'storage', (e) ->
if cb = $.syncing[e.key]
cb JSON.parse e.newValue
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
$.delete = (keys) ->
unless keys instanceof Array
keys = [keys]

View File

@ -1,9 +1,3 @@
<% if (type === 'userjs') { %>
# Opera doesn't support the @match metadata key,
# return 4chan X here if we're not on 4chan.
return unless /^(boards|images|sys)\.4chan\.org$/.test location.hostname
<% } %>
Conf = {}
c = console
d = document

View File

@ -127,8 +127,6 @@ Main =
<% if (type === 'crx') { %>
$.addClass doc, 'webkit'
$.addClass doc, 'blink'
<% } else if (type === 'userjs') { %>
$.addClass doc, 'presto'
<% } else { %>
$.addClass doc, 'gecko'
<% } %>
@ -151,13 +149,9 @@ Main =
$.addClass doc, style
setStyle()
return unless mainStyleSheet
if window.MutationObserver
observer = new MutationObserver setStyle
observer.observe mainStyleSheet,
attributes: true
attributeFilter: ['href']
else
$.on mainStyleSheet, 'DOMAttrModified', setStyle
new MutationObserver(setStyle).observe mainStyleSheet,
attributes: true
attributeFilter: ['href']
initReady: ->
if d.title is '4chan - 404 Not Found'
@ -252,12 +246,10 @@ Main =
checkUpdate: ->
return unless Conf['Check for Updates'] and Main.isThisPageLegit()
# Check for updates after:
# - 6 hours since the last update on Opera because it lacks auto-updating.
# - 7 days since the last update on Chrome/Firefox.
# Check for updates after 7 days since the last update.
# After that, check for updates every day if we still haven't updated.
now = Date.now()
freq = <% if (type === 'userjs') { %>6 * $.HOUR<% } else { %>7 * $.DAY<% } %>
freq = 7 * $.DAY
items =
lastupdate: 0
lastchecked: 0

View File

@ -52,19 +52,6 @@ ImageExpand =
return
setFitness: ->
(if @checked then $.addClass else $.rmClass) doc, @name.toLowerCase().replace /\s+/g, '-'
<% if (type === 'userjs') { %>
# XXX Opera doesn't support CSS vh.
return unless @name is 'Fit height'
if @checked
$.on window, 'resize', ImageExpand.resize
unless ImageExpand.style
ImageExpand.style = $.addStyle null
ImageExpand.resize()
else
$.off window, 'resize', ImageExpand.resize
resize: ->
ImageExpand.style.textContent = ":root.fit-height .full-image {max-height:#{doc.clientHeight}px}"
<% } %>
toggle: (post) ->
{thumb} = post.file

View File

@ -4,12 +4,10 @@ Sauce =
links = []
for link in Conf['sauces'].split '\n'
continue if link[0] is '#'
try
links.push @createSauceLink link.trim()
links.push @createSauceLink link.trim() if link[0] isnt '#'
catch err
# Don't add random text plz.
continue
return unless links.length
@links = links
@link = $.el 'a', target: '_blank'

View File

@ -15,7 +15,8 @@
"run_at": "document_start"
}],
"homepage_url": "<%= meta.page %>",
"minimum_chrome_version": "26",
"minimum_chrome_version": "27",
"minimum_opera_version": "15",
"permissions": [
"storage"
]

View File

@ -114,8 +114,7 @@ ThreadUpdater =
By sending the `If-Modified-Since` header we get a proper status code, and no response.
This saves bandwidth for both the user and the servers and avoid unnecessary computation.
###
# XXX 304 -> 0 in Opera
[text, klass] = if req.status in [0, 304]
[text, klass] = if req.status is 304
[null, null]
else
["#{req.statusText} (#{req.status})", 'warning']

View File

@ -182,9 +182,7 @@ Unread =
else
Favicon.default
<% if (type !== 'crx') { %>
<% if (type === 'userscript') { %>
# `favicon.href = href` doesn't work on Firefox.
# `favicon.href = href` isn't enough on Opera.
# Opera won't always update the favicon if the href didn't change.
$.add d.head, Favicon.el
<% } %>

View File

@ -330,7 +330,6 @@ QR =
post = Get.postFromNode @
text = ">>#{post}\n"
if (s = sel.toString().trim()) and post is Get.postFromNode sel.anchorNode
# XXX Opera doesn't retain `\n`s?
s = s.replace /\n/g, '\n>'
text += ">#{s}\n"
@ -501,7 +500,6 @@ QR =
else if @ is QR.selected
(QR.posts[index-1] or QR.posts[index+1]).select()
QR.posts.splice index, 1
return unless window.URL
URL.revokeObjectURL @URL
lock: (lock=true) ->
@isLocked = lock
@ -558,25 +556,14 @@ QR =
@filename = "#{file.name} (#{$.bytesToString file.size})"
@nodes.el.title = @filename
@nodes.label.hidden = false if QR.spoiler
URL.revokeObjectURL @URL if window.URL
URL.revokeObjectURL @URL
@showFileData()
unless /^image/.test file.type
@nodes.el.style.backgroundImage = null
return
@setThumbnail()
setThumbnail: (fileURL) ->
# XXX Opera does not support blob URL
setThumbnail: ->
# Create a redimensioned thumbnail.
unless window.URL
unless fileURL
reader = new FileReader()
reader.onload = (e) =>
@setThumbnail e.target.result
reader.readAsDataURL @file
return
else
fileURL = URL.createObjectURL @file
img = $.el 'img'
img.onload = =>
@ -588,7 +575,7 @@ QR =
s *= 3 if @file.type is 'image/gif' # let them animate
{height, width} = img
if height < s or width < s
@URL = fileURL if window.URL
@URL = fileURL
@nodes.el.style.backgroundImage = "url(#{@URL})"
return
if height <= width
@ -601,10 +588,6 @@ QR =
cv.height = img.height = height
cv.width = img.width = width
cv.getContext('2d').drawImage img, 0, 0, width, height
unless window.URL
@nodes.el.style.backgroundImage = "url(#{cv.toDataURL()})"
delete @URL
return
URL.revokeObjectURL fileURL
applyBlob = (blob) =>
@URL = URL.createObjectURL blob
@ -622,6 +605,7 @@ QR =
applyBlob new Blob [ui8a], type: 'image/png'
fileURL = URL.createObjectURL @file
img.src = fileURL
rmFile: ->
delete @file
@ -630,7 +614,6 @@ QR =
@nodes.el.style.backgroundImage = null
@nodes.label.hidden = true if QR.spoiler
@showFileData()
return unless window.URL
URL.revokeObjectURL @URL
showFileData: ->
if @file
@ -652,22 +635,17 @@ QR =
QR.nodes.com.value = @com
@nodes.span.textContent = @com
reader.readAsText file
dragStart: ->
$.addClass @, 'drag'
dragEnd: ->
$.rmClass @, 'drag'
dragEnter: ->
$.addClass @, 'over'
dragLeave: ->
$.rmClass @, 'over'
dragStart: -> $.addClass @, 'drag'
dragEnd: -> $.rmClass @, 'drag'
dragEnter: -> $.addClass @, 'over'
dragLeave: -> $.rmClass @, 'over'
dragOver: (e) ->
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
drop: ->
el = $ '.drag', @parentNode
$.rmClass el, 'drag' # Opera doesn't fire dragEnd if we drop it on something else
$.rmClass @, 'over'
$.rmClass @, 'over'
return unless @draggable
el = $ '.drag', @parentNode
index = (el) -> [el.parentNode.children...].indexOf el
oldIndex = index el
newIndex = index @
@ -700,12 +678,8 @@ QR =
img: imgContainer.firstChild
input: input
if window.MutationObserver
observer = new MutationObserver @load.bind @
observer.observe @nodes.challenge,
childList: true
else
$.on @nodes.challenge, 'DOMNodeInserted', @load.bind @
new MutationObserver(@load.bind @).observe @nodes.challenge,
childList: true
$.on imgContainer, 'click', @reload.bind @
$.on input, 'keydown', @keydown.bind @
@ -836,10 +810,6 @@ QR =
# Add empty mimeType to avoid errors with URLs selected in Window's file dialog.
QR.mimeTypes.push ''
nodes.fileInput.max = $('input[name=MAX_FILE_SIZE]').value
<% if (type !== 'userjs') { %>
# Opera's accept attribute is fucked up
nodes.fileInput.accept = "text/*, #{mimeTypes}"
<% } %>
QR.spoiler = !!$ 'input[name=spoiler]'
nodes.spoiler.hidden = !QR.spoiler
@ -1018,11 +988,6 @@ QR =
QR.status()
response: ->
<% if (type === 'userjs') { %>
# The upload.onload callback is not called
# or at least not in time with Opera.
QR.req.upload.onload()
<% } %>
{req} = QR
delete QR.req

View File

@ -28,21 +28,6 @@ QuotePreview =
cb: QuotePreview.mouseout
asapTest: -> qp.firstElementChild
<% if (type === 'userjs') { %>
# XXX Opera workaround for "no mouseout fired" bug.
# Remove it once Opera uses Blink.
root = @
workaround = (e) ->
if @ is root
e.stopPropagation()
return
$.event 'mouseout', null, root
$.off d, 'mousemove', workaround
$.off root, 'mousemove', workaround
$.on d, 'mousemove', workaround
$.on root, 'mousemove', workaround
<% } %>
return unless origin = g.posts["#{boardID}.#{postID}"]
if Conf['Quote Highlighting']