Compare commits
107 Commits
Author | SHA1 | Date |
---|---|---|
|
787d5b1c37 | |
|
58a38460f9 | |
|
02c0594509 | |
|
552e65520d | |
|
af6cf59fdd | |
|
7fcbc7c039 | |
|
fe15a1633f | |
|
07b6a8d8bf | |
|
afee3205dc | |
|
0674268548 | |
|
be749ff31f | |
|
207dff9e67 | |
|
b2fc048450 | |
|
a771b26952 | |
|
2fc1134124 | |
|
6ee91fbb25 | |
|
072ece28cd | |
|
e7a48b467f | |
|
0ba765e181 | |
|
8f75c8d315 | |
|
e67eb36443 | |
|
ffef920411 | |
|
99760d2eb7 | |
|
dc58ac8532 | |
|
f91dfc4ba7 | |
|
75bc6636b2 | |
|
eecd3133b8 | |
|
06682d3222 | |
|
6c286150fa | |
|
1df716d694 | |
|
7715c43ba1 | |
|
465c10137e | |
|
a3a82d6087 | |
|
b2d1bfdf4a | |
|
cc647700f0 | |
|
e865c41504 | |
|
a64719424d | |
|
643919c62f | |
|
11b1338841 | |
|
af70f93ec0 | |
|
d45df7d629 | |
|
4e6d09a774 | |
|
0bea1baa24 | |
|
2a0546fd65 | |
|
0089798f86 | |
|
2d98767bdd | |
|
25fc9af6fa | |
|
4f7fc33cbd | |
|
9d012c676f | |
|
7b4e3f250a | |
|
35b1a2c309 | |
|
00846a56cc | |
|
62e20aca51 | |
|
a9a879b273 | |
|
4615113a44 | |
|
5faabf04bd | |
|
ec6eb34e22 | |
|
ad5ace57cb | |
|
94846f28f3 | |
|
13ee04dcc2 | |
|
a5accb5be3 | |
|
6b7df230b6 | |
|
639b72620b | |
|
74c0e0319f | |
|
0a2b4c7538 | |
|
bd2aa28afc | |
|
98982c6145 | |
|
82b88b2146 | |
|
2af04fb767 | |
|
eb32411fa7 | |
|
81ad370af1 | |
|
358d44b3bd | |
|
795298c94f | |
|
f8e573a8b5 | |
|
fe6381ccfd | |
|
18e75842f8 | |
|
a2f6aab453 | |
|
82c2ef8442 | |
|
fad1e5e689 | |
|
cb7cb397c1 | |
|
d35dc6036e | |
|
1f97b6d19c | |
|
0f9cb4e167 | |
|
08fa6c7bfa | |
|
21cab163d5 | |
|
068c461070 | |
|
54966185d1 | |
|
fa02bd8f7b | |
|
5f88797a93 | |
|
62673d3790 | |
|
eb6b67f612 | |
|
13aa8595e7 | |
|
d818c7dc66 | |
|
6a951ea8d3 | |
|
f7d399c41a | |
|
3e6e3d5855 | |
|
aa7b9649d1 | |
|
684f6c15fe | |
|
429c432dc5 | |
|
afa1ef0fb0 | |
|
633410061a | |
|
49328a4b4a | |
|
4a8d6f49f4 | |
|
d90ebd48f3 | |
|
552b997ba3 | |
|
b7768ca8a9 | |
|
26893fbb4f |
|
@ -1,5 +1,7 @@
|
||||||
chrome_point_plus/vendor/
|
chrome_point_plus/vendor/
|
||||||
/nbproject/private/
|
/nbproject/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
npm-debug.log
|
||||||
publish
|
publish
|
||||||
vendor/
|
vendor/
|
||||||
|
/.idea/
|
|
@ -0,0 +1,119 @@
|
||||||
|
{
|
||||||
|
"disallowImplicitTypeConversion": [ "numeric", "boolean", "binary" ],
|
||||||
|
"disallowKeywordsOnNewLine": [ "else" ],
|
||||||
|
"disallowMixedSpacesAndTabs": true,
|
||||||
|
"disallowMultipleLineBreaks": true,
|
||||||
|
"disallowMultipleLineStrings": true,
|
||||||
|
"disallowNewlineBeforeBlockStatements": true,
|
||||||
|
"disallowOperatorBeforeLineBreak": [ "+", "-", "*", "/", "." ],
|
||||||
|
"disallowPaddingNewlinesInBlocks": true,
|
||||||
|
"disallowQuotedKeysInObjects": "allButReserved",
|
||||||
|
"disallowSpaceAfterObjectKeys": true,
|
||||||
|
"disallowSpaceAfterPrefixUnaryOperators": [ "++", "--", "+", "-" ],
|
||||||
|
"disallowSpaceBeforePostfixUnaryOperators": true,
|
||||||
|
"disallowSpacesInCallExpression": true,
|
||||||
|
"disallowSpacesInFunctionExpression": {
|
||||||
|
"beforeOpeningRoundBrace": true
|
||||||
|
},
|
||||||
|
"disallowSpacesInNamedFunctionExpression": {
|
||||||
|
"beforeOpeningRoundBrace": true
|
||||||
|
},
|
||||||
|
"disallowSpacesInsideParentheses": true,
|
||||||
|
"disallowTrailingComma": true,
|
||||||
|
"disallowTrailingWhitespace": true,
|
||||||
|
"disallowYodaConditions": true,
|
||||||
|
"requireBlocksOnNewline": true,
|
||||||
|
"requireCapitalizedConstructors": true,
|
||||||
|
"requireCommaBeforeLineBreak": true,
|
||||||
|
"requireCurlyBraces": [
|
||||||
|
"if",
|
||||||
|
"else",
|
||||||
|
"for",
|
||||||
|
"while",
|
||||||
|
"do",
|
||||||
|
"try",
|
||||||
|
"catch"
|
||||||
|
],
|
||||||
|
"requireDotNotation": true,
|
||||||
|
"requireLineBreakAfterVariableAssignment": true,
|
||||||
|
"requireLineFeedAtFileEnd": true,
|
||||||
|
"requirePaddingNewlinesBeforeKeywords": [
|
||||||
|
"do",
|
||||||
|
"for",
|
||||||
|
"if",
|
||||||
|
"switch",
|
||||||
|
"try",
|
||||||
|
"void",
|
||||||
|
"while",
|
||||||
|
"with",
|
||||||
|
"return"
|
||||||
|
],
|
||||||
|
"requireSpaceAfterBinaryOperators": true,
|
||||||
|
"requireSpaceAfterKeywords": [
|
||||||
|
"do",
|
||||||
|
"for",
|
||||||
|
"if",
|
||||||
|
"else",
|
||||||
|
"switch",
|
||||||
|
"case",
|
||||||
|
"try",
|
||||||
|
"catch",
|
||||||
|
"void",
|
||||||
|
"while",
|
||||||
|
"with",
|
||||||
|
"return",
|
||||||
|
"typeof"
|
||||||
|
],
|
||||||
|
"requireSpaceAfterLineComment": {
|
||||||
|
"allExcept": [ "#", "=" ]
|
||||||
|
},
|
||||||
|
"requireSpaceAfterPrefixUnaryOperators": [ "~", "!" ],
|
||||||
|
"requireSpaceBeforeBinaryOperators": [
|
||||||
|
"=",
|
||||||
|
"+",
|
||||||
|
"-",
|
||||||
|
"/",
|
||||||
|
"*",
|
||||||
|
"==",
|
||||||
|
"===",
|
||||||
|
"!=",
|
||||||
|
"!=="
|
||||||
|
],
|
||||||
|
"requireSpaceBeforeBlockStatements": true,
|
||||||
|
"requireSpaceBeforeKeywords": [
|
||||||
|
"else",
|
||||||
|
"while",
|
||||||
|
"catch"
|
||||||
|
],
|
||||||
|
"requireSpaceBeforeObjectValues": true,
|
||||||
|
"requireSpaceBetweenArguments": true,
|
||||||
|
"requireSpacesInAnonymousFunctionExpression": {
|
||||||
|
"beforeOpeningCurlyBrace": true
|
||||||
|
},
|
||||||
|
"requireSpacesInForStatement": true,
|
||||||
|
"requireSpacesInFunctionDeclaration": {
|
||||||
|
"beforeOpeningCurlyBrace": true
|
||||||
|
},
|
||||||
|
"requireSpacesInFunctionExpression": {
|
||||||
|
"beforeOpeningCurlyBrace": true
|
||||||
|
},
|
||||||
|
"requireSpacesInNamedFunctionExpression": {
|
||||||
|
"beforeOpeningCurlyBrace": true
|
||||||
|
},
|
||||||
|
"requireSpacesInsideObjectBrackets": "allButNested",
|
||||||
|
"validateIndentation": 4,
|
||||||
|
"validateLineBreaks": "LF",
|
||||||
|
"validateParameterSeparator": ", ",
|
||||||
|
|
||||||
|
|
||||||
|
"excludeFiles": [
|
||||||
|
"chrome_point_plus/js/bquery_ajax.js",
|
||||||
|
"chrome_point_plus/js/markitup/sets/markdown/set.js",
|
||||||
|
"chrome_point_plus/js/point-plus.js",
|
||||||
|
"chrome_point_plus/vendor/**",
|
||||||
|
"nbproject/**",
|
||||||
|
"node_modules/**",
|
||||||
|
"publish/**",
|
||||||
|
"vendor/**"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
.git/**
|
||||||
|
chrome_point_plus/js/bquery_ajax.js
|
||||||
|
chrome_point_plus/js/markitup/sets/markdown/set.js
|
||||||
|
chrome_point_plus/js/point-plus.js
|
||||||
|
chrome_point_plus/vendor/**
|
||||||
|
nbproject/**
|
||||||
|
node_modules/**
|
||||||
|
publish/**
|
||||||
|
vendor/**
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"bitwise": true,
|
||||||
|
"camelcase": false,
|
||||||
|
"curly": true,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"es3": false,
|
||||||
|
"forin": true,
|
||||||
|
"freeze": true,
|
||||||
|
"latedef": true,
|
||||||
|
"maxlen": 120,
|
||||||
|
"maxparams": 4,
|
||||||
|
"newcap": true,
|
||||||
|
"noarg": true,
|
||||||
|
"noempty": true,
|
||||||
|
"nonbsp": true,
|
||||||
|
"quotmark": "single",
|
||||||
|
"shadow": "inner",
|
||||||
|
"undef": true,
|
||||||
|
"unused": true,
|
||||||
|
"browser": true,
|
||||||
|
"jquery": true,
|
||||||
|
"globals": {
|
||||||
|
"chrome": true,
|
||||||
|
"console": true
|
||||||
|
}
|
||||||
|
}
|
11
Gruntfile.js
|
@ -1,5 +1,5 @@
|
||||||
var vendorCopy = [
|
var vendorCopy = [
|
||||||
'jquery/jquery.min.js',
|
'jquery/dist/jquery.min.js',
|
||||||
|
|
||||||
'fancybox/source/jquery.fancybox.pack.js',
|
'fancybox/source/jquery.fancybox.pack.js',
|
||||||
'fancybox/source/helpers/jquery.fancybox-media.js',
|
'fancybox/source/helpers/jquery.fancybox-media.js',
|
||||||
|
@ -18,12 +18,15 @@ var vendorCopy = [
|
||||||
|
|
||||||
vendorCopy.push({
|
vendorCopy.push({
|
||||||
expand: true,
|
expand: true,
|
||||||
src: [ 'vendor/fancybox/source/*.png' ],
|
src: [
|
||||||
|
'vendor/fancybox/source/*.png',
|
||||||
|
'vendor/fancybox/source/*.gif'
|
||||||
|
],
|
||||||
dest: 'chrome_point_plus/'
|
dest: 'chrome_point_plus/'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* global module */
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
// Настройки
|
// Настройки
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
@ -46,7 +49,7 @@ module.exports = function(grunt) {
|
||||||
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
|
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
|
||||||
globalReplace: true
|
globalReplace: true
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Загрузить плагины
|
// Загрузить плагины
|
||||||
|
|
33
README.md
|
@ -28,3 +28,36 @@
|
||||||
* Сразу присылать пулл-реквесты с шашкой наголо
|
* Сразу присылать пулл-реквесты с шашкой наголо
|
||||||
* Поставить в магазинах Opera и Chrome оценку расширению
|
* Поставить в магазинах Opera и Chrome оценку расширению
|
||||||
* Задонатить (см. таб Feedback в настройках)
|
* Задонатить (см. таб Feedback в настройках)
|
||||||
|
|
||||||
|
### Как собрать из исходников
|
||||||
|
|
||||||
|
Для сборки используется Node.js. Ещё нужно глобально установить npm-пакет grunt-cli (`npm i -g grunt-cli`).
|
||||||
|
|
||||||
|
Все команды ниже нужно выполнять в корне проекта.
|
||||||
|
|
||||||
|
Установить npm и bower зависимости и разложить библиотеки по местам:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
Если у вас нет Node.js, то вы можете посмотреть используемые библиотеки в файле `bower.json` и положить их
|
||||||
|
в `chrome_point_plus/vendor`.
|
||||||
|
|
||||||
|
Проверить кодстайл:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
Поднять версию ([примеры](https://github.com/vojtajina/grunt-bump/blob/master/README.md#usage-examples)):
|
||||||
|
|
||||||
|
```
|
||||||
|
grunt bump
|
||||||
|
```
|
||||||
|
|
||||||
|
Запустить сборку расширения браузером:
|
||||||
|
|
||||||
|
```
|
||||||
|
/bin/bash pack_chromium.sh /usr/bin/chromium /path/to/repository/chrome_point_plus /path/to/private/key.pem
|
||||||
|
```
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "chrome-point-plus",
|
"name": "chrome-point-plus",
|
||||||
"version": "1.35.1",
|
"version": "1.42.1",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Alexey Skobkin"
|
"Alexey Skobkin"
|
||||||
],
|
],
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
"chrome_point_plus/vendors/**"
|
"chrome_point_plus/vendors/**"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jquery": "~1.10.1",
|
"jquery": "~3",
|
||||||
"fancybox": "~2.1.5",
|
"fancybox": "~2.1.5",
|
||||||
"markitup": "~1.1.14",
|
"markitup": "~1.1.14",
|
||||||
"soundcloud": "git@github.com:soundcloud/Widget-JS-API.git"
|
"soundcloud": "git@github.com:soundcloud/Widget-JS-API.git"
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
"message": "Alexey Skobkin"
|
"message": "Alexey Skobkin"
|
||||||
},
|
},
|
||||||
"ext_page_action_title": {
|
"ext_page_action_title": {
|
||||||
"message": "Point+ settings"
|
"message": "Settings"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"options_page_title": {
|
||||||
|
"message": "Point+ settings"
|
||||||
|
},
|
||||||
|
|
||||||
"options_text_saved": {
|
"options_text_saved": {
|
||||||
"message": "Reload page to apply changes."
|
"message": "Reload page to apply changes."
|
||||||
|
@ -47,9 +50,6 @@
|
||||||
"option_fancybox_bind_images_to_one_flow": {
|
"option_fancybox_bind_images_to_one_flow": {
|
||||||
"message": "Bind all images to one Fancybox gallery"
|
"message": "Bind all images to one Fancybox gallery"
|
||||||
},
|
},
|
||||||
"option_fancybox_smart_hints": {
|
|
||||||
"message": "Generate image caption from tags"
|
|
||||||
},
|
|
||||||
"option_images_load_original": {
|
"option_images_load_original": {
|
||||||
"message": "Load original images instead of thumbnails"
|
"message": "Load original images instead of thumbnails"
|
||||||
},
|
},
|
||||||
|
@ -57,13 +57,13 @@
|
||||||
"message": "Enable embedding ▼"
|
"message": "Enable embedding ▼"
|
||||||
},
|
},
|
||||||
"option_images_load_booru": {
|
"option_images_load_booru": {
|
||||||
"message": "Load pictures from Booru, Tumblr, etc"
|
"message": "Load pictures from Booru, Tumblr, etc via @NokitaKaze server"
|
||||||
},
|
},
|
||||||
"option_audios_parse_links": {
|
"option_audios_parse_links": {
|
||||||
"message": "Audio from direct links"
|
"message": "Audio from direct links"
|
||||||
},
|
},
|
||||||
"option_videos_parse_links": {
|
"option_videos_parse_links": {
|
||||||
"message": "Video from direct links"
|
"message": "Video from direct links ▼"
|
||||||
},
|
},
|
||||||
"option_videos_parse_webm": {
|
"option_videos_parse_webm": {
|
||||||
"message": "Only webm"
|
"message": "Only webm"
|
||||||
|
@ -71,30 +71,24 @@
|
||||||
"option_videos_parse_all_links": {
|
"option_videos_parse_all_links": {
|
||||||
"message": "Parse all links"
|
"message": "Parse all links"
|
||||||
},
|
},
|
||||||
"option_videos_parse_leave_links": {
|
|
||||||
"message": "Leave original link"
|
|
||||||
},
|
|
||||||
"option_embedding_soundcloud": {
|
"option_embedding_soundcloud": {
|
||||||
"message": "Soundcloud ▼"
|
"message": "Soundcloud"
|
||||||
},
|
|
||||||
"option_embedding_soundcloud_orig_link": {
|
|
||||||
"message": "Leave original link"
|
|
||||||
},
|
},
|
||||||
"option_embedding_pleercom": {
|
"option_embedding_pleercom": {
|
||||||
"message": "Pleer.com ▼"
|
"message": "Pleer.com"
|
||||||
},
|
|
||||||
"option_embedding_pleercom_nokita_server": {
|
|
||||||
"message": "Use Nokita's server (deprecated)"
|
|
||||||
},
|
},
|
||||||
"option_embedding_coubcom": {
|
"option_embedding_coubcom": {
|
||||||
"message": "Coub.com ▼"
|
"message": "Coub.com"
|
||||||
},
|
|
||||||
"option_embedding_coubcom_orig_link": {
|
|
||||||
"message": "Leave original link"
|
|
||||||
},
|
},
|
||||||
"option_embedding_twitter_tweets": {
|
"option_embedding_twitter_tweets": {
|
||||||
"message": "Twitter"
|
"message": "Twitter"
|
||||||
},
|
},
|
||||||
|
"option_embedding_instagram_posts": {
|
||||||
|
"message": "Instagram"
|
||||||
|
},
|
||||||
|
"option_embedding_remove_original_link": {
|
||||||
|
"message": "Remove original link"
|
||||||
|
},
|
||||||
"option_nsfw": {
|
"option_nsfw": {
|
||||||
"message": "NSFW content filtering"
|
"message": "NSFW content filtering"
|
||||||
},
|
},
|
||||||
|
@ -119,6 +113,12 @@
|
||||||
"option_ajax_comments": {
|
"option_ajax_comments": {
|
||||||
"message": "Send comments via AJAX (CTRL+Enter)"
|
"message": "Send comments via AJAX (CTRL+Enter)"
|
||||||
},
|
},
|
||||||
|
"option_right_panel": {
|
||||||
|
"message": "Right side panel"
|
||||||
|
},
|
||||||
|
"option_right_panel_to_unread": {
|
||||||
|
"message": "\"Go to unread comment\" button"
|
||||||
|
},
|
||||||
"option_fluid_layout": {
|
"option_fluid_layout": {
|
||||||
"message": "Fluid layout"
|
"message": "Fluid layout"
|
||||||
},
|
},
|
||||||
|
@ -172,10 +172,19 @@
|
||||||
"message": "Your hints about users"
|
"message": "Your hints about users"
|
||||||
},
|
},
|
||||||
"option_other_comments_count_refresh":{
|
"option_other_comments_count_refresh":{
|
||||||
"message": "Refresh unread posts and comments count in left menu"
|
"message": "Refresh unread posts and comments count in the sidebar"
|
||||||
},
|
},
|
||||||
"option_other_comments_count_refresh_title":{
|
"option_other_comments_count_refresh_title":{
|
||||||
"message": "Show counts in the title of tabs"
|
"message": "Page title"
|
||||||
|
},
|
||||||
|
"option_other_move_all_to_menu":{
|
||||||
|
"message": "Move \"All posts\" to left menu"
|
||||||
|
},
|
||||||
|
"option_other_remove_fucking_button":{
|
||||||
|
"message": "Remove the fucking button"
|
||||||
|
},
|
||||||
|
"option_other_post_draft_save":{
|
||||||
|
"message": "Save post drafts"
|
||||||
},
|
},
|
||||||
|
|
||||||
"options_feedback_text": {
|
"options_feedback_text": {
|
||||||
|
@ -185,5 +194,11 @@
|
||||||
|
|
||||||
"msg_comment_send_failed":{
|
"msg_comment_send_failed":{
|
||||||
"message": "Comment send error:"
|
"message": "Comment send error:"
|
||||||
|
},
|
||||||
|
"msg_saving_post_draft":{
|
||||||
|
"message": "Saving the post..."
|
||||||
|
},
|
||||||
|
"msg_success_recommendation": {
|
||||||
|
"message": "is recommended"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
"message": "Алексей Скобкин"
|
"message": "Алексей Скобкин"
|
||||||
},
|
},
|
||||||
"ext_page_action_title": {
|
"ext_page_action_title": {
|
||||||
"message": "Настройки Point+"
|
"message": "Настройки"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"options_page_title": {
|
||||||
|
"message": "Настройки Point+"
|
||||||
|
},
|
||||||
|
|
||||||
"options_text_saved": {
|
"options_text_saved": {
|
||||||
"message": "Для применения изменений перезагрузите страницу."
|
"message": "Для применения изменений перезагрузите страницу."
|
||||||
|
@ -47,9 +50,6 @@
|
||||||
"option_fancybox_bind_images_to_one_flow": {
|
"option_fancybox_bind_images_to_one_flow": {
|
||||||
"message": "Связать все картинки в одну галерею Fancybox"
|
"message": "Связать все картинки в одну галерею Fancybox"
|
||||||
},
|
},
|
||||||
"option_fancybox_smart_hints": {
|
|
||||||
"message": "Генерировать подписи к картинкам из тегов"
|
|
||||||
},
|
|
||||||
"option_images_load_original": {
|
"option_images_load_original": {
|
||||||
"message": "Загружать оригиналы вместо миниатюр"
|
"message": "Загружать оригиналы вместо миниатюр"
|
||||||
},
|
},
|
||||||
|
@ -57,13 +57,13 @@
|
||||||
"message": "Включить встраивание ▼"
|
"message": "Включить встраивание ▼"
|
||||||
},
|
},
|
||||||
"option_images_load_booru": {
|
"option_images_load_booru": {
|
||||||
"message": "Загружать картинки с Booru, Tumblr и т.п."
|
"message": "Загружать картинки с Booru, Tumblr и т.п. через сервер @NokitaKaze"
|
||||||
},
|
},
|
||||||
"option_audios_parse_links": {
|
"option_audios_parse_links": {
|
||||||
"message": "Аудио по прямой ссылке"
|
"message": "Аудио по прямой ссылке"
|
||||||
},
|
},
|
||||||
"option_videos_parse_links": {
|
"option_videos_parse_links": {
|
||||||
"message": "Видео по прямой ссылке"
|
"message": "Видео по прямой ссылке ▼"
|
||||||
},
|
},
|
||||||
"option_videos_parse_webm": {
|
"option_videos_parse_webm": {
|
||||||
"message": "Только webm"
|
"message": "Только webm"
|
||||||
|
@ -71,30 +71,24 @@
|
||||||
"option_videos_parse_all_links": {
|
"option_videos_parse_all_links": {
|
||||||
"message": "Все ссылки на видео"
|
"message": "Все ссылки на видео"
|
||||||
},
|
},
|
||||||
"option_videos_parse_leave_links": {
|
|
||||||
"message": "Оставлять ссылку на видео"
|
|
||||||
},
|
|
||||||
"option_embedding_soundcloud": {
|
"option_embedding_soundcloud": {
|
||||||
"message": "Soundcloud ▼"
|
"message": "Soundcloud"
|
||||||
},
|
|
||||||
"option_embedding_soundcloud_orig_link": {
|
|
||||||
"message": "Не убирать ссылку"
|
|
||||||
},
|
},
|
||||||
"option_embedding_pleercom": {
|
"option_embedding_pleercom": {
|
||||||
"message": "Pleer.com ▼"
|
"message": "Pleer.com"
|
||||||
},
|
|
||||||
"option_embedding_pleercom_nokita_server": {
|
|
||||||
"message": "Использовать сервер @NokitaKaze (deprecated)"
|
|
||||||
},
|
},
|
||||||
"option_embedding_coubcom": {
|
"option_embedding_coubcom": {
|
||||||
"message": "Coub.com ▼"
|
"message": "Coub.com"
|
||||||
},
|
|
||||||
"option_embedding_coubcom_orig_link": {
|
|
||||||
"message": "Не убирать ссылку"
|
|
||||||
},
|
},
|
||||||
"option_embedding_twitter_tweets": {
|
"option_embedding_twitter_tweets": {
|
||||||
"message": "Twitter"
|
"message": "Twitter"
|
||||||
},
|
},
|
||||||
|
"option_embedding_instagram_posts": {
|
||||||
|
"message": "Instagram"
|
||||||
|
},
|
||||||
|
"option_embedding_remove_original_link": {
|
||||||
|
"message": "Удалять оригинальную ссылку"
|
||||||
|
},
|
||||||
"option_nsfw": {
|
"option_nsfw": {
|
||||||
"message": "Фильтрация NSFW-контента"
|
"message": "Фильтрация NSFW-контента"
|
||||||
},
|
},
|
||||||
|
@ -119,6 +113,12 @@
|
||||||
"option_ajax_comments": {
|
"option_ajax_comments": {
|
||||||
"message": "Отправка комментариев через AJAX (CTRL+Enter)"
|
"message": "Отправка комментариев через AJAX (CTRL+Enter)"
|
||||||
},
|
},
|
||||||
|
"option_right_panel": {
|
||||||
|
"message": "Боковая панель справа"
|
||||||
|
},
|
||||||
|
"option_right_panel_to_unread": {
|
||||||
|
"message": "Кнопка \"Перейти к непрочитанному\""
|
||||||
|
},
|
||||||
"option_fluid_layout": {
|
"option_fluid_layout": {
|
||||||
"message": ""Резиновая" вёрстка (растянуть сайт по горизонтали)"
|
"message": ""Резиновая" вёрстка (растянуть сайт по горизонтали)"
|
||||||
},
|
},
|
||||||
|
@ -172,10 +172,19 @@
|
||||||
"message": "Заметки о пользователях на полях"
|
"message": "Заметки о пользователях на полях"
|
||||||
},
|
},
|
||||||
"option_other_comments_count_refresh":{
|
"option_other_comments_count_refresh":{
|
||||||
"message": "Обновляем количество непрочитанных комментариев и постов в ленте"
|
"message": "Обновление количества непрочитанных постов и комментариев в сайдбаре"
|
||||||
},
|
},
|
||||||
"option_other_comments_count_refresh_title":{
|
"option_other_comments_count_refresh_title":{
|
||||||
"message": "Указываем кол-во комментариев и сообщений в заголовке страницы"
|
"message": "В заголовке страницы"
|
||||||
|
},
|
||||||
|
"option_other_move_all_to_menu":{
|
||||||
|
"message": "Переместить \"Всё подряд\" в левое меню"
|
||||||
|
},
|
||||||
|
"option_other_remove_fucking_button":{
|
||||||
|
"message": "Убрать ёбаную кнопку"
|
||||||
|
},
|
||||||
|
"option_other_post_draft_save":{
|
||||||
|
"message": "Сохранение черновика поста"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,5 +195,11 @@
|
||||||
|
|
||||||
"msg_comment_send_failed":{
|
"msg_comment_send_failed":{
|
||||||
"message": "Ошибка отправки комментария:"
|
"message": "Ошибка отправки комментария:"
|
||||||
|
},
|
||||||
|
"msg_saving_post_draft":{
|
||||||
|
"message": "Сохранение поста..."
|
||||||
|
},
|
||||||
|
"msg_success_recommendation": {
|
||||||
|
"message": "рекомендовано"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
background-image: url('chrome-extension://__MSG_@@extension_id__/vendor/fancybox/source/fancybox_overlay.png');
|
background-image: url('chrome-extension://__MSG_@@extension_id__/vendor/fancybox/source/fancybox_overlay.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fancybox-nav {
|
||||||
|
/* To supress errors */
|
||||||
|
background-image: url('chrome-extension://__MSG_@@extension_id__/vendor/fancybox/source/blank.gif'); /* helps IE */
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (min-device-pixel-ratio: 1.5) {
|
@media only screen and (min-device-pixel-ratio: 1.5) {
|
||||||
#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span {
|
#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span {
|
||||||
background-image: url('chrome-extension://__MSG_@@extension_id__/vendor/fancybox/source/fancybox_sprite@2x.png');
|
background-image: url('chrome-extension://__MSG_@@extension_id__/vendor/fancybox/source/fancybox_sprite@2x.png');
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
/* @ before username */
|
/* Posts */
|
||||||
#main #content a.user:before {
|
#content .post-content a.user:before,
|
||||||
|
/* Subscribers */
|
||||||
|
#content .users span.user:before,
|
||||||
|
/* Subscriptions */
|
||||||
|
#content .users .info a.user:before {
|
||||||
content: "@";
|
content: "@";
|
||||||
}
|
}
|
||||||
/* Fix for recommendations in the feed */
|
/* Fix for recommendations */
|
||||||
#main #content .rec .user:before {
|
#content .post-content .rec .user:before {
|
||||||
margin-right: -4px;
|
margin-right: -3px;
|
||||||
}
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pp-right-panel {
|
||||||
|
width: 32px;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
right: 3px;
|
||||||
|
opacity: .3;
|
||||||
|
transition: opacity 500ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pp-right-panel:hover {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 500ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pp-right-panel #pp-go-to-unread {
|
||||||
|
background-image: url("/img/menu-my.png");
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pp-right-panel span#pp-unread-count {
|
||||||
|
position: relative;
|
||||||
|
top: 7px;
|
||||||
|
left: 11px;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
|
@ -94,7 +94,7 @@ p
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 10px 15px 5px;
|
padding: 20px 15px 5px;
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
|
@ -28,31 +28,40 @@ div#markItUpText-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Auto-loaded Booru pictures */
|
/* Auto-loaded Booru pictures */
|
||||||
.booru_pic {
|
.booru_pic, .instagram-post-embedded {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
float: none !important;
|
float: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.booru_pic img {
|
.booru_pic img, .instagram-post-embedded img {
|
||||||
border: none;
|
border: none;
|
||||||
max-width: 60%;
|
max-width: 60%;
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Labels in post */
|
/* Unique ID and Recomendation */
|
||||||
.post .post-id a .cn.changed_background {
|
.pp-post-counters
|
||||||
|
{
|
||||||
|
float: left;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post .post-id a .authors_unique_count, .post .post-id a .recommendation_count {
|
.pp-unique-comments
|
||||||
padding: 0 .5em;
|
{
|
||||||
font-weight: normal;
|
margin-right: .5em;
|
||||||
color: #35587c;
|
|
||||||
background-color: #f2f2eb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.post .post-id a .recommendation_count {
|
/* @todo i18n */
|
||||||
margin-left: 0.2em;
|
.pp-unique-comments::before
|
||||||
background-color: #f2eceb;
|
{
|
||||||
|
content: 'Комментаторов: ';
|
||||||
|
}
|
||||||
|
|
||||||
|
.pp-recommendation-count::before
|
||||||
|
{
|
||||||
|
content: 'Рекомендаций: ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NSFW-content */
|
/* NSFW-content */
|
||||||
|
@ -115,7 +124,7 @@ div#markItUpText-input {
|
||||||
right: 5px;
|
right: 5px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
display: none;
|
display: none;
|
||||||
background-image: url("//point.im/img/btn-edit.png");
|
background-image: url('//point.im/img/btn-edit.png');
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
@ -173,8 +182,9 @@ div#markItUpText-input {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
background-image: url('chrome-extension://__MSG_@@extension_id__/images/nesting-point.png');
|
background-image: url('chrome-extension://__MSG_@@extension_id__/images/nesting-point.svg');
|
||||||
background-repeat: repeat-x;
|
background-repeat: repeat-x;
|
||||||
|
background-position: right center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#comments.nesting_level .post:hover .info::before {
|
#comments.nesting_level .post:hover .info::before {
|
||||||
|
@ -182,3 +192,68 @@ div#markItUpText-input {
|
||||||
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pp-progress.reply-form {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pp-progress.reply-form::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
height: 4px;
|
||||||
|
background: linear-gradient(to right, #fff, #9aacbe, #fff);
|
||||||
|
-webkit-animation: loading 1s;
|
||||||
|
-webkit-animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes loading {
|
||||||
|
from {
|
||||||
|
background-position: -640px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "All" link in left menu */
|
||||||
|
#pp-left-menu-all {
|
||||||
|
/* Opened Lock icon from default point.im icon set */
|
||||||
|
background-image: url('/img/icon-private-inactive.png') !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Highlight post with new comments */
|
||||||
|
.pp-post-unread {
|
||||||
|
background-color: #EEFFEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Video from direct links */
|
||||||
|
.pp-video-player {
|
||||||
|
display: block;
|
||||||
|
max-width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Audio from direct links */
|
||||||
|
.pp-audio-player {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Coub embedded video */
|
||||||
|
.pp-video-player-coub {
|
||||||
|
max-width: 640px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New posts and comments auto refresh in left menu by @NokitaKaze */
|
||||||
|
.pp-left-menu-refreshed {
|
||||||
|
background-color: #f2ebee;
|
||||||
|
color: #7c3558;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pp-iframe-unread-refresh {
|
||||||
|
width: 600px;
|
||||||
|
height: 300px;
|
||||||
|
display: none;
|
||||||
|
}
|
Before Width: | Height: | Size: 43 B |
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1003 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 651 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg version="1" xmlns="http://www.w3.org/2000/svg" height="10" width="10"><circle cx="5" cy="5" r="3" fill="#9aacbe"/></svg>
|
After Width: | Height: | Size: 125 B |
|
@ -1,77 +1,96 @@
|
||||||
// Maintaining options version
|
var VERSION = (function() {
|
||||||
chrome.storage.sync.get('options_version', function(data) {
|
|
||||||
var pp_version = getVersion();
|
|
||||||
console.info('Point+ %s. Options are for %s.', pp_version, data.options_version);
|
|
||||||
|
|
||||||
if (data.options_version != pp_version) {
|
|
||||||
chrome.tabs.create({url: 'options.html'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Adding notification click event listener
|
|
||||||
chrome.notifications.onClicked.addListener(function(notificationId) {
|
|
||||||
// Detecting notification type
|
|
||||||
if (notificationId.indexOf('comment_') === 0) {
|
|
||||||
tab_url = 'https://point.im/' + notificationId.replace(/comment_/g, '');
|
|
||||||
} else if (notificationId.indexOf('post_') === 0) {
|
|
||||||
tab_url = 'https://point.im/' + notificationId.replace(/post_/g, '');
|
|
||||||
}
|
|
||||||
console.log('Notification %s clicked! Opening new tab: %s', notificationId, tab_url);
|
|
||||||
|
|
||||||
if (tab_url !== undefined) {
|
|
||||||
chrome.tabs.create({
|
|
||||||
url: tab_url
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Crutches and bikes
|
|
||||||
/**
|
/**
|
||||||
* Inject several JS files
|
* @deprecated XMLHttpRequest in the background worker is deprecated
|
||||||
* @param {number} tabId Unique ID of tab which requested injection
|
* according to the Chrome warning. But we definitely need synchronous
|
||||||
* @param {Object[]} files Array of objects of files to inject
|
* AJAX here
|
||||||
* @param {function} onAllInjected allback function running when injection ends
|
|
||||||
*/
|
*/
|
||||||
function injectJS(tabId, files, onAllInjected) {
|
var xhr = new XMLHttpRequest(),
|
||||||
var item = files.shift();
|
manifest;
|
||||||
if (item) {
|
|
||||||
console.log('Injecting JS "%s" to the tab #%s', item.file, tabId);
|
|
||||||
|
|
||||||
if ('file' in item) {
|
xhr.open('GET', chrome.extension.getURL('manifest.json'), false);
|
||||||
chrome.tabs.executeScript(tabId ? tabId : null, {
|
xhr.send(null);
|
||||||
file: item.file,
|
|
||||||
runAt: item.runAt || 'document_start'
|
|
||||||
}, function(result) {
|
|
||||||
console.info('"%s" injected to the tab #%s', item.file, tabId);
|
|
||||||
|
|
||||||
injectJS(tabId, files, onAllInjected);
|
manifest = JSON.parse(xhr.responseText);
|
||||||
|
|
||||||
|
return manifest.version;
|
||||||
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Вставка нескольких файлов друг за другом
|
||||||
|
* @param {Array} files Список файлов
|
||||||
|
* @param {Function} injectOne Функция вставки одного файла. Должна принимать file и callback
|
||||||
|
* @param {Function} [onAllInjected] Функция обработки ответа
|
||||||
|
* @param {Array} [results] Результаты вставки (их не нужно передавать при запуске извне)
|
||||||
|
*/
|
||||||
|
function injectFiles(files, injectOne, onAllInjected, results) {
|
||||||
|
results = results || [];
|
||||||
|
|
||||||
|
if (files.length) {
|
||||||
|
injectOne(files.shift(), function(res) {
|
||||||
|
if (res) {
|
||||||
|
results.unshift(res[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
injectFiles(files, injectOne, onAllInjected, results);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
onAllInjected();
|
onAllInjected(results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo Implement injectCSS (because JS execution working always after CSS injection)
|
/**
|
||||||
|
* @constructor Менеджер сообщений
|
||||||
// Message listener
|
*/
|
||||||
|
function MessageListener() {
|
||||||
|
/* jshint unused:false */
|
||||||
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
|
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
|
||||||
// @todo Check if sender.tab may be undefined in some cases
|
if (this.isMethodAvailable(message)) {
|
||||||
console.log('Received message from tab #%s: %O', sender.tab ? sender.tab.id : 'undefined', message);
|
console.info('Call #%s() method for tab #%s', message.type, this.getTabId(sender));
|
||||||
|
this[message.type].apply(this, arguments);
|
||||||
|
|
||||||
if (message) {
|
|
||||||
switch (message.type) {
|
|
||||||
case 'showPageAction':
|
|
||||||
chrome.pageAction.show(sender.tab.id);
|
|
||||||
sendResponse(true);
|
|
||||||
|
|
||||||
console.log('Showed pageAction for tab #%s', sender.tab.id);
|
|
||||||
|
|
||||||
// Fuck You, Chrome API documentation!!11
|
|
||||||
return true;
|
return true;
|
||||||
break;
|
} else {
|
||||||
|
console.warn('Method #%s() called from tab #%s does not exists', message.type, this.getTabId(sender));
|
||||||
|
|
||||||
case 'showNotification':
|
return false;
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
/* jshint unused:true */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} message Сообщение
|
||||||
|
* @returns {Boolean} Есть ли необходимый метод в MessageListener
|
||||||
|
*/
|
||||||
|
MessageListener.prototype.isMethodAvailable = function(message) {
|
||||||
|
return message && message.type && typeof this[message.type] === 'function';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} sender
|
||||||
|
* @returns {Number|Null} Идентификатор вкладки, с которой пришло сообщение
|
||||||
|
*/
|
||||||
|
MessageListener.prototype.getTabId = function(sender) {
|
||||||
|
return sender.tab && sender.tab.id || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} message Сообщение
|
||||||
|
* @param {Object} sender Отправитель
|
||||||
|
* @param {Function} sendResponse Коллбек для обработки результата
|
||||||
|
*/
|
||||||
|
MessageListener.prototype.showPageAction = function(message, sender, sendResponse) {
|
||||||
|
chrome.pageAction.show(this.getTabId(sender));
|
||||||
|
sendResponse(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Показывает нотификацию
|
||||||
|
* @param {Object} message Сообщение
|
||||||
|
* @param {Object} sender Отправитель
|
||||||
|
* @param {Function} sendResponse Коллбек для обработки результата
|
||||||
|
*/
|
||||||
|
MessageListener.prototype.showNotification = function(message, sender, sendResponse) {
|
||||||
chrome.notifications.create(
|
chrome.notifications.create(
|
||||||
message.notificationId, {
|
message.notificationId, {
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
|
@ -86,113 +105,100 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
|
||||||
sendResponse(true);
|
sendResponse(true);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
};
|
||||||
// Fuck You, Chrome API documentation!!11
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'getManifestVersion':
|
|
||||||
sendResponse({version: getVersion()});
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since 1.19.1
|
* Получает версию плагина из манифеста
|
||||||
|
* @param {Object} message Сообщение
|
||||||
|
* @param {Object} sender Отправитель
|
||||||
|
* @param {Function} sendResponse Коллбек для обработки результата
|
||||||
*/
|
*/
|
||||||
case 'injectJSFile':
|
MessageListener.prototype.getManifestVersion = function(message, sender, sendResponse) {
|
||||||
console.log('Executing JS: %s', message.file);
|
sendResponse({ version: VERSION });
|
||||||
chrome.tabs.executeScript(sender.tab.id ? sender.tab.id : null, {
|
};
|
||||||
file: message.file,
|
|
||||||
runAt: message.runAt || 'document_start'
|
|
||||||
}, function() {
|
|
||||||
sendResponse(true);
|
|
||||||
|
|
||||||
console.info('JS file executed: "%s"', message.file);
|
/**
|
||||||
return true;
|
* @param {Object} message Сообщение
|
||||||
});
|
*/
|
||||||
|
MessageListener.prototype.getFiles = function(message, defaultRunAt) {
|
||||||
|
var files;
|
||||||
|
|
||||||
// Fuck You, Chrome API documentation!
|
if (! message.files) {
|
||||||
return true;
|
return false;
|
||||||
break;
|
|
||||||
|
|
||||||
// Inject several files
|
|
||||||
case 'executeJSFiles':
|
|
||||||
//console.debug('Received JS file list: %O', message.files);
|
|
||||||
|
|
||||||
if (message.files.length) {
|
|
||||||
injectJS(sender.tab.id ? sender.tab.id : null, message.files, function() {
|
|
||||||
// @fixme does not sending response now!
|
|
||||||
console.info('All scripts executed');
|
|
||||||
|
|
||||||
sendResponse(true);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
files = Array.isArray(message.files) ? message.files : [ message.files ];
|
||||||
* May be not?
|
|
||||||
* But I don't want to block some shit-code execution
|
|
||||||
*/
|
|
||||||
sendResponse(false);
|
|
||||||
|
|
||||||
console.warn('No scripts executed (empty script array)');
|
return files.map(function(file) {
|
||||||
|
return {
|
||||||
|
file: typeof file === 'string' ? file : file.file,
|
||||||
|
runAt: file.runAt || defaultRunAt
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
// Fuck You, Chrome API documentation!
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated since 1.19.1
|
* Вставляет JS-файлы во вкладку
|
||||||
|
* @param {Object} message Сообщение
|
||||||
|
* @param {Object} sender Отправитель
|
||||||
|
* @param {Function} sendResponse Коллбек для обработки результата
|
||||||
*/
|
*/
|
||||||
case 'injectCSSFile':
|
MessageListener.prototype.executeJSFiles = function(message, sender, sendResponse) {
|
||||||
console.log('Injecting CSS: "%s"', message.file);
|
var tabId = this.getTabId(sender);
|
||||||
chrome.tabs.insertCSS(sender.tab.id ? sender.tab.id : null, {
|
|
||||||
file: message.file
|
|
||||||
}, function() {
|
|
||||||
// @todo message response callback processing
|
|
||||||
//sendResponse(true);
|
|
||||||
|
|
||||||
console.info('CSS file "%s" injected', message.file);
|
injectFiles(
|
||||||
});
|
this.getFiles(message, 'document_end'),
|
||||||
|
function(file, callback) {
|
||||||
|
chrome.tabs.executeScript(tabId, file, callback);
|
||||||
|
},
|
||||||
|
sendResponse
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Fuck You, Chrome API documentation!
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'injectCSSCode':
|
|
||||||
if (message.code !== undefined) {
|
|
||||||
chrome.tabs.insertCSS(sender.tab.id ? sender.tab.id : null, {
|
|
||||||
code: message.code
|
|
||||||
}, function() {
|
|
||||||
// @todo message response callback processing
|
|
||||||
//sendResponse(true);
|
|
||||||
|
|
||||||
console.info('CSS code injected: \n%s', message.file);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fuck You, Chrome API documentation!
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sendResponse(false);
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Getting version from manifest.json
|
|
||||||
function getVersion() {
|
|
||||||
/**
|
/**
|
||||||
* @deprecated XMLHttpRequest in the background worker is deprecated
|
* Вставляет CSS-файлы во вкладку
|
||||||
* according to the Chrome warning. But we definitely need synchronous
|
* @param {Object} message Сообщение
|
||||||
* AJAX here
|
* @param {Object} sender Отправитель
|
||||||
|
* @param {Function} sendResponse Коллбек для обработки результата
|
||||||
*/
|
*/
|
||||||
var xhr = new XMLHttpRequest();
|
MessageListener.prototype.injectCSSFiles = function(message, sender, sendResponse) {
|
||||||
xhr.open('GET', chrome.extension.getURL('manifest.json'), false);
|
var tabId = this.getTabId(sender);
|
||||||
xhr.send(null);
|
|
||||||
var manifest = JSON.parse(xhr.responseText);
|
injectFiles(
|
||||||
return manifest.version;
|
this.getFiles(message),
|
||||||
|
function(file, callback) {
|
||||||
|
chrome.tabs.insertCSS(tabId, file, callback);
|
||||||
|
},
|
||||||
|
sendResponse
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
new MessageListener();
|
||||||
|
|
||||||
|
// Maintaining options version
|
||||||
|
chrome.storage.sync.get('options_version', function(data) {
|
||||||
|
console.info('Point+ %s. Options are for %s.', VERSION, data.options_version);
|
||||||
|
|
||||||
|
if (data.options_version !== VERSION) {
|
||||||
|
chrome.tabs.create({ url: 'options.html' });
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Adding notification click event listener
|
||||||
|
chrome.notifications.onClicked.addListener(function(notificationId) {
|
||||||
|
var tab_url;
|
||||||
|
|
||||||
|
// Detecting notification type
|
||||||
|
if (notificationId.indexOf('comment_') === 0) {
|
||||||
|
tab_url = 'https://point.im/' + notificationId.replace(/comment_/g, '');
|
||||||
|
} else if (notificationId.indexOf('post_') === 0) {
|
||||||
|
tab_url = 'https://point.im/' + notificationId.replace(/post_/g, '');
|
||||||
|
}
|
||||||
|
console.log('Notification %s clicked! Opening new tab: %s', notificationId, tab_url);
|
||||||
|
|
||||||
|
if (tab_url !== undefined) {
|
||||||
|
chrome.tabs.create({
|
||||||
|
url: tab_url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
function $ajax_prot(settings){
|
|
||||||
if (settings==undefined){return;}
|
|
||||||
if (settings['url'] ==undefined){return;}this.url=settings['url'];
|
|
||||||
if (settings['async'] !==undefined){this.async =settings['async'];}
|
|
||||||
if (settings['type'] !==undefined){this.type =settings['type'];}
|
|
||||||
if (settings['postdata']!==undefined){this.postdata=settings['postdata'];}
|
|
||||||
if (settings['dont_set_content_type']!==undefined){
|
|
||||||
this.dont_set_content_type=settings['dont_set_content_type'];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.xhr=new XMLHttpRequest();
|
|
||||||
this.xhr.parent =this;
|
|
||||||
this.xhr.settings=settings;
|
|
||||||
this.xhr.success =settings['success'];
|
|
||||||
this.xhr.error =settings['error'];
|
|
||||||
this.xhr.onreadystatechange=this.change;
|
|
||||||
this.xhr.open(this.type, this.url, this.async);
|
|
||||||
if ((this.type=='POST')&& !this.dont_set_content_type){
|
|
||||||
this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
||||||
}
|
|
||||||
if (settings.headers!==undefined){
|
|
||||||
for (var i=0;i<settings.headers.length;i++){
|
|
||||||
this.xhr.setRequestHeader(settings.headers[i][0], settings.headers[i][1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.xhr.send(this.postdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
$ajax_prot.prototype={
|
|
||||||
version: '0.0.5a',
|
|
||||||
url: '',
|
|
||||||
type: 'GET',
|
|
||||||
async: true,
|
|
||||||
postdata:null,
|
|
||||||
xhr: null,
|
|
||||||
dont_set_content_type: false,
|
|
||||||
change:function(){
|
|
||||||
if (this.readyState!==4){return;}
|
|
||||||
if (this.status==200){
|
|
||||||
if (this.success!==undefined){this.success(this.responseText,this.textStatus,this);}
|
|
||||||
}else{
|
|
||||||
if (this.error !==undefined){this.error(this.responseText,this.textStatus,this);}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ajax=function (settings){return new $ajax_prot(settings);}
|
|
||||||
|
|
||||||
function urlencode(text){return encodeURIComponent(text);}
|
|
||||||
|
|
||||||
function sad_safe_reg(text){
|
|
||||||
var ar='.-\\/[]{}?+';
|
|
||||||
var s=''; for (var i=0;i<text.length;i++){
|
|
||||||
if ((' '+ar).indexOf(text[i])>0){
|
|
||||||
s+='\\'+text[i];
|
|
||||||
}else{
|
|
||||||
s+=text[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sad_xml_getnode(node,path){//node as domNode
|
|
||||||
if ('' ==path){return node;}
|
|
||||||
if ('#'==path){return node.textContent || node.text;}
|
|
||||||
|
|
||||||
var ri=new RegExp('^([a-z0-9.:_-]*)(\\|[0-9]+)?(/?(.*))?','i');
|
|
||||||
var t=path.match(ri);
|
|
||||||
if (t[1].length<1){return undefined;}
|
|
||||||
if (t[2]==undefined){t[2]='';}
|
|
||||||
if (t[4]==undefined){t[4]='';}
|
|
||||||
|
|
||||||
var k=parseInt(t[2].substr(1));
|
|
||||||
if (!(k>0)){k=1;}
|
|
||||||
var r=new RegExp('^'+sad_safe_reg(t[1])+'$');
|
|
||||||
for (var i=0;i<node.childNodes.length;i++){
|
|
||||||
if (r.test(node.childNodes[i].nodeName)){
|
|
||||||
k--;if (k==0){return sad_xml_getnode(node.childNodes[i],t[4]);}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sad_xml_attribute(node,name){
|
|
||||||
if (node==undefined){return undefined;}
|
|
||||||
var r=new RegExp('^'+sad_safe_reg(name)+'$','i');
|
|
||||||
for (var i=0;i<node.attributes.length;i++){
|
|
||||||
if (r.test(node.attributes[i].nodeName)){return node.attributes[i].nodeValue;}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function sad_x2n(xml){
|
|
||||||
return xml.responseXML.childNodes[xml.responseXML.childNodes.length-1];
|
|
||||||
}
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
function MessageSender() {}
|
||||||
|
function stub() {}
|
||||||
|
|
||||||
|
MessageSender.prototype.css = function(files, callback) {
|
||||||
|
this.sendMessage({
|
||||||
|
type: 'injectCSSFiles',
|
||||||
|
files: files
|
||||||
|
}, callback || stub);
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageSender.prototype.js = function(files, callback) {
|
||||||
|
this.sendMessage({
|
||||||
|
type: 'executeJSFiles',
|
||||||
|
files: files
|
||||||
|
}, callback || stub);
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageSender.prototype.sendMessage = function() {
|
||||||
|
chrome.runtime.sendMessage.apply(chrome.runtime, arguments);
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Объект для получения опций
|
||||||
|
* @constructor {OptionsManager}
|
||||||
|
* @param {Object} options Хеш настроек
|
||||||
|
*/
|
||||||
|
function OptionsManager(options) {
|
||||||
|
this._options = options || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} optionName Имя опции
|
||||||
|
* @returns {Boolean|String|Null} Значение опции
|
||||||
|
*/
|
||||||
|
OptionsManager.prototype.get = function(optionName) {
|
||||||
|
return this._options.hasOwnProperty(optionName) ? this._options[optionName].value : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет, равна ли опция значению value. Если value не переданно, проверяет задана ли она и не равна ли false/''
|
||||||
|
* @param {String} optionName Имя опции
|
||||||
|
* @param {Boolean|String} [value=true] Значение опции
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
OptionsManager.prototype.is = function(optionName, value) {
|
||||||
|
if (typeof value !== 'undefined') {
|
||||||
|
return this.get(optionName) === value;
|
||||||
|
} else {
|
||||||
|
return Boolean(this.get(optionName));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Object} Хеш опций
|
||||||
|
*/
|
||||||
|
OptionsManager.prototype.getOptions = function() {
|
||||||
|
return this._options;
|
||||||
|
};
|
|
@ -4,7 +4,7 @@
|
||||||
* При создании сохраняет версию, восстанавливает настройки, слушает изменения на инпутах.
|
* При создании сохраняет версию, восстанавливает настройки, слушает изменения на инпутах.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function Options() {
|
function OptionsPage() {
|
||||||
this.form = document.querySelector('form');
|
this.form = document.querySelector('form');
|
||||||
|
|
||||||
this.listenTabs();
|
this.listenTabs();
|
||||||
|
@ -25,7 +25,7 @@ function Options() {
|
||||||
* Получает версию настроек. Если она не равна версии приложения, записывает в сторедж плагина настройки из инпутов
|
* Получает версию настроек. Если она не равна версии приложения, записывает в сторедж плагина настройки из инпутов
|
||||||
* и версию приложения.
|
* и версию приложения.
|
||||||
*/
|
*/
|
||||||
Options.prototype.updateOptionsFromFrom = function() {
|
OptionsPage.prototype.updateOptionsFromFrom = function() {
|
||||||
chrome.storage.sync.get('options_version', function(data) {
|
chrome.storage.sync.get('options_version', function(data) {
|
||||||
this.logVersion(data.options_version);
|
this.logVersion(data.options_version);
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ Options.prototype.updateOptionsFromFrom = function() {
|
||||||
}, function() {
|
}, function() {
|
||||||
console.log('Default options initialized. Version upgraded to %s.', this.version);
|
console.log('Default options initialized. Version upgraded to %s.', this.version);
|
||||||
|
|
||||||
|
/* global confirm */
|
||||||
if (! confirm(chrome.i18n.getMessage('options_text_new_version'))) {
|
if (! confirm(chrome.i18n.getMessage('options_text_new_version'))) {
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
@ -51,7 +52,7 @@ Options.prototype.updateOptionsFromFrom = function() {
|
||||||
/**
|
/**
|
||||||
* Сохраняет настройки
|
* Сохраняет настройки
|
||||||
*/
|
*/
|
||||||
Options.prototype.save = function() {
|
OptionsPage.prototype.save = function() {
|
||||||
var ppOptions = this.getValues();
|
var ppOptions = this.getValues();
|
||||||
|
|
||||||
console.log('Saving options: %O', ppOptions);
|
console.log('Saving options: %O', ppOptions);
|
||||||
|
@ -62,7 +63,7 @@ Options.prototype.save = function() {
|
||||||
/**
|
/**
|
||||||
* Получает настройки из стореджа плагина, устанавливает соответствующим инпутам соответствующие значения.
|
* Получает настройки из стореджа плагина, устанавливает соответствующим инпутам соответствующие значения.
|
||||||
*/
|
*/
|
||||||
Options.prototype.restore = function() {
|
OptionsPage.prototype.restore = function() {
|
||||||
this.checkOldStyle();
|
this.checkOldStyle();
|
||||||
|
|
||||||
chrome.storage.sync.get('options', function(data) {
|
chrome.storage.sync.get('options', function(data) {
|
||||||
|
@ -80,6 +81,7 @@ Options.prototype.restore = function() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'enum':
|
case 'enum':
|
||||||
|
case 'plain':
|
||||||
input.value = data.value;
|
input.value = data.value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -97,19 +99,19 @@ Options.prototype.restore = function() {
|
||||||
/**
|
/**
|
||||||
* @returns {Object} Хеш настроек вида { имя_настроки: значение_настройки }
|
* @returns {Object} Хеш настроек вида { имя_настроки: значение_настройки }
|
||||||
*/
|
*/
|
||||||
Options.prototype.getValues = function() {
|
OptionsPage.prototype.getValues = function() {
|
||||||
return this._options;
|
return this._options;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Event} event Событие изменения
|
* @param {Event} event Событие изменения
|
||||||
*/
|
*/
|
||||||
Options.prototype._onChange = function(event) {
|
OptionsPage.prototype._onChange = function(event) {
|
||||||
this.updateOptionFromInput(event.target);
|
this.updateOptionFromInput(event.target);
|
||||||
this.save();
|
this.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
Options.prototype.updateOptionFromInput = function(input) {
|
OptionsPage.prototype.updateOptionFromInput = function(input) {
|
||||||
var key = this.getOptionKey(input.name);
|
var key = this.getOptionKey(input.name);
|
||||||
|
|
||||||
if (this.isBoolean(input)) {
|
if (this.isBoolean(input)) {
|
||||||
|
@ -122,6 +124,11 @@ Options.prototype.updateOptionFromInput = function(input) {
|
||||||
type: 'enum',
|
type: 'enum',
|
||||||
value: input.value
|
value: input.value
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
this._options[key] = {
|
||||||
|
type: 'plain',
|
||||||
|
value: input.value
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,7 +136,7 @@ Options.prototype.updateOptionFromInput = function(input) {
|
||||||
* @param {HTMLElement} option Элемент опции
|
* @param {HTMLElement} option Элемент опции
|
||||||
* @returns {Boolean} Является ли настройка булевой
|
* @returns {Boolean} Является ли настройка булевой
|
||||||
*/
|
*/
|
||||||
Options.prototype.isBoolean = function(option) {
|
OptionsPage.prototype.isBoolean = function(option) {
|
||||||
return option.getAttribute('type') === 'checkbox';
|
return option.getAttribute('type') === 'checkbox';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,7 +145,7 @@ Options.prototype.isBoolean = function(option) {
|
||||||
* @param {HTMLElement} option Элемент опции
|
* @param {HTMLElement} option Элемент опции
|
||||||
* @returns {Boolean} Является ли настройка енумом
|
* @returns {Boolean} Является ли настройка енумом
|
||||||
*/
|
*/
|
||||||
Options.prototype.isEnum = function(option) {
|
OptionsPage.prototype.isEnum = function(option) {
|
||||||
return option.getAttribute('type') === 'radio';
|
return option.getAttribute('type') === 'radio';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,7 +153,7 @@ Options.prototype.isEnum = function(option) {
|
||||||
* @param {String} name Имя инпута
|
* @param {String} name Имя инпута
|
||||||
* @returns {String} Ключ для хеша настроек
|
* @returns {String} Ключ для хеша настроек
|
||||||
*/
|
*/
|
||||||
Options.prototype.getOptionKey = function(name) {
|
OptionsPage.prototype.getOptionKey = function(name) {
|
||||||
return name.replace(/-/g, '_');
|
return name.replace(/-/g, '_');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,7 +161,7 @@ Options.prototype.getOptionKey = function(name) {
|
||||||
* @param {String} Ключ хеша настроек
|
* @param {String} Ключ хеша настроек
|
||||||
* @returns {String} Имя инпута
|
* @returns {String} Имя инпута
|
||||||
*/
|
*/
|
||||||
Options.prototype.getOptionName = function(key) {
|
OptionsPage.prototype.getOptionName = function(key) {
|
||||||
return key.replace(/_/g, '-');
|
return key.replace(/_/g, '-');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -162,32 +169,35 @@ Options.prototype.getOptionName = function(key) {
|
||||||
* Выводит в консоль версию настроек и версию плагина
|
* Выводит в консоль версию настроек и версию плагина
|
||||||
* @param {String} optionsVersion
|
* @param {String} optionsVersion
|
||||||
*/
|
*/
|
||||||
Options.prototype.logVersion = function(optionsVersion) {
|
OptionsPage.prototype.logVersion = function(optionsVersion) {
|
||||||
console.info('Point+ %s, local options are for %s', this.version, optionsVersion);
|
console.info('Point+ %s, local options are for %s', this.version, optionsVersion);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Добавляет номер версии в подвал
|
* Добавляет номер версии в подвал
|
||||||
*/
|
*/
|
||||||
Options.prototype.showVersion = function() {
|
OptionsPage.prototype.showVersion = function() {
|
||||||
document.querySelector('#version').innerHTML = this.version;
|
document.querySelector('#version').innerHTML = this.version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Проверяет, не старого ли формата настройки. И если старого, то удаляет их.
|
* Проверяет, не старого ли формата настройки. И если старого, то удаляет их.
|
||||||
*/
|
*/
|
||||||
Options.prototype.checkOldStyle = function() {
|
OptionsPage.prototype.checkOldStyle = function() {
|
||||||
chrome.storage.sync.get('option_fancybox', function(data) {
|
chrome.storage.sync.get('option_fancybox', function(data) {
|
||||||
if ((data.option_fancybox === true) || (data.option_fancybox === false)) {
|
if ((data.option_fancybox === true) || (data.option_fancybox === false)) {
|
||||||
console.log('Found old-style options. Cleaning...');
|
console.log('Found old-style options. Cleaning...');
|
||||||
|
|
||||||
chrome.storage.sync.get(null, function(data) {
|
chrome.storage.sync.get(null, function(data) {
|
||||||
|
var option;
|
||||||
|
|
||||||
console.log('Old data: %O', data);
|
console.log('Old data: %O', data);
|
||||||
|
|
||||||
for (option in data) {
|
for (option in data) {
|
||||||
|
if (data.hasOwnProperty(option)) {
|
||||||
chrome.storage.sync.remove(option);
|
chrome.storage.sync.remove(option);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log('All old data removed');
|
console.log('All old data removed');
|
||||||
});
|
});
|
||||||
|
@ -198,7 +208,7 @@ Options.prototype.checkOldStyle = function() {
|
||||||
/**
|
/**
|
||||||
* Показывает плашку про то, что настройки сохранились и надо обновить страницу
|
* Показывает плашку про то, что настройки сохранились и надо обновить страницу
|
||||||
*/
|
*/
|
||||||
Options.prototype.updateStatus = function() {
|
OptionsPage.prototype.updateStatus = function() {
|
||||||
this.status = this.status || document.querySelector('.saved');
|
this.status = this.status || document.querySelector('.saved');
|
||||||
|
|
||||||
this.status.classList.remove('hidden');
|
this.status.classList.remove('hidden');
|
||||||
|
@ -207,7 +217,7 @@ Options.prototype.updateStatus = function() {
|
||||||
/**
|
/**
|
||||||
* Слушает события на табах
|
* Слушает события на табах
|
||||||
*/
|
*/
|
||||||
Options.prototype.listenTabs = function() {
|
OptionsPage.prototype.listenTabs = function() {
|
||||||
var options = this;
|
var options = this;
|
||||||
|
|
||||||
options._selectedItem = document.querySelector('.tabs-item.selected');
|
options._selectedItem = document.querySelector('.tabs-item.selected');
|
||||||
|
@ -229,4 +239,4 @@ Options.prototype.listenTabs = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
new Options();
|
new OptionsPage();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Point+",
|
"name": "Point+",
|
||||||
"version": "1.35.1",
|
"version": "1.42.1",
|
||||||
"default_locale": "ru",
|
"default_locale": "ru",
|
||||||
"author": "__MSG_ext_author__",
|
"author": "__MSG_ext_author__",
|
||||||
"homepage_url": "https://bitbucket.org/skobkin/chrome_point_plus",
|
"homepage_url": "https://bitbucket.org/skobkin/chrome_point_plus",
|
||||||
|
@ -27,9 +27,10 @@
|
||||||
{
|
{
|
||||||
"matches": ["http://*.point.im/*", "https://*.point.im/*"],
|
"matches": ["http://*.point.im/*", "https://*.point.im/*"],
|
||||||
"js": [
|
"js": [
|
||||||
"vendor/jquery/jquery.min.js",
|
"vendor/jquery/dist/jquery.min.js",
|
||||||
|
|
||||||
"js/bquery_ajax.js",
|
"js/options-manager.js",
|
||||||
|
"js/message-sender.js",
|
||||||
|
|
||||||
"js/point-plus.js"
|
"js/point-plus.js"
|
||||||
],
|
],
|
||||||
|
@ -58,6 +59,7 @@
|
||||||
"https://player.soundcloud.com/*",
|
"https://player.soundcloud.com/*",
|
||||||
"https://api.kanaria.ru/point/*",
|
"https://api.kanaria.ru/point/*",
|
||||||
"https://*.twitter.com/*",
|
"https://*.twitter.com/*",
|
||||||
|
"https://api.instagram.com/*",
|
||||||
"https://coub.com/embed/*",
|
"https://coub.com/embed/*",
|
||||||
"storage",
|
"storage",
|
||||||
"notifications",
|
"notifications",
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
.pp-notification {
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 40px;
|
||||||
|
right: 40px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
transition: all 10s ease-in;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pp-notification a,
|
||||||
|
.pp-notification a:visited {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pp-notification-success {
|
||||||
|
background: #4CAF50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pp-notification.pp-fade {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
|
@ -0,0 +1,311 @@
|
||||||
|
/**
|
||||||
|
* Находит элемент #comments, и если он есть, начинает слушать на нём события
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function AjaxComments() {
|
||||||
|
var comments = document.querySelector('#comments');
|
||||||
|
|
||||||
|
if (comments) {
|
||||||
|
this._comments = comments;
|
||||||
|
this.listen(comments);
|
||||||
|
|
||||||
|
this.listenFirstComments();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Вешает обработчики. Магия в последнем параметре addEventListener
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.listen = function(elem) {
|
||||||
|
elem.addEventListener('submit', this.onSubmit.bind(this), true);
|
||||||
|
elem.addEventListener('keypress', this.onKeypress.bind(this), true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Слушает отправки первых комментариев
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.listenFirstComments = function() {
|
||||||
|
var posts = document.querySelectorAll('.post-content');
|
||||||
|
|
||||||
|
// Чтобы не ловить события на чём попало и мочь использовать useCapture, приходится
|
||||||
|
// получать все post-content и на каждый вешать обработчики.
|
||||||
|
Array.prototype.forEach.call(posts, this.listen.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обрабатывает событие отправки формы
|
||||||
|
* @param {Event} event Событие отправки
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.onSubmit = function(event) {
|
||||||
|
var $form = $(event.target);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
if ($form.hasClass('reply-form')) {
|
||||||
|
this.submit($form);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет, выбран ли файл. Если да — отправляет форму с перезагрузкой, иначе — аяксом
|
||||||
|
* @param {jQuery} $form Элемент формы
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.submit = function($form) {
|
||||||
|
var proc;
|
||||||
|
|
||||||
|
if (this.isFileSelected($form)) {
|
||||||
|
$form.submit();
|
||||||
|
} else {
|
||||||
|
proc = new AjaxCommentProcessor($form);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обрабатывает нажатия кнопок. Если это сочетание Ctrl|⌘+Enter, отправляет коммент
|
||||||
|
* @param {Event} event Событие нажатия кнопки
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.onKeypress = function(event) {
|
||||||
|
var $form;
|
||||||
|
|
||||||
|
if (this.isProperKeys(event)) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
$form = $(event.target).closest('.reply-form');
|
||||||
|
|
||||||
|
if ($form.length) {
|
||||||
|
this.submit($form);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет, что нажато нужное сочетание клавишь
|
||||||
|
* @param {Event} event Событие нажатия
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.isProperKeys = function(event) {
|
||||||
|
return (event.keyCode === 10 || event.keyCode === 13) && (event.ctrlKey || event.metaKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {jQuery} $form
|
||||||
|
* @return {Boolean} Выбран ли файл
|
||||||
|
*/
|
||||||
|
AjaxComments.prototype.isFileSelected = function($form) {
|
||||||
|
var attach = $form.get(0).elements.attach;
|
||||||
|
|
||||||
|
if (attach) {
|
||||||
|
return Boolean(attach.files && attach.files.length);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создаётся при каждой отправке комментария
|
||||||
|
* @param {jQuery} $form Элемент формы, на которой это произошло
|
||||||
|
*/
|
||||||
|
function AjaxCommentProcessor($form) {
|
||||||
|
this._$form = $form;
|
||||||
|
this._$post = $form.closest('.post');
|
||||||
|
this._$textarea = $form.find('textarea');
|
||||||
|
|
||||||
|
this._text = this._$textarea.val();
|
||||||
|
this._CSRF = $form.get(0).elements.csrf_token.value;
|
||||||
|
|
||||||
|
this._actionUrl = this._$form.attr('action');
|
||||||
|
this._postId = this._$post.data('id');
|
||||||
|
this._commentId = this._$post.data('comment-id');
|
||||||
|
|
||||||
|
this.sendComment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Регулярка для урла, проверяюшая, не рекомендация ли это
|
||||||
|
* @type {RegExp}
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.recommendationReg = /^\/[^/]*\/r$/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отправляет комментарий
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.sendComment = function() {
|
||||||
|
this.setProgress(true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: this.getUrl(),
|
||||||
|
data: {
|
||||||
|
text: this._text,
|
||||||
|
comment_id: this._commentId
|
||||||
|
},
|
||||||
|
beforeSend: this.beforeSend.bind(this),
|
||||||
|
error: this.onError.bind(this),
|
||||||
|
success: this.onSuccess.bind(this)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Boolean} true — это коммент-рекомендация, fasle — обычный коммент
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.isRecommendation = function() {
|
||||||
|
return this._isRec || (this._isRec = this.constructor.recommendationReg.test(this._actionUrl));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {String} Адрес, на который слать запрос
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.getUrl = function() {
|
||||||
|
// Если это рекомендация комментария
|
||||||
|
if (this.isRecommendation() && this._commentId) {
|
||||||
|
return '/api/post/' + this._postId + '/' + this._commentId + '/r';
|
||||||
|
} else {
|
||||||
|
return '/api/post' + this._actionUrl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Подкладывает CSRF-токен в заголовки запроса
|
||||||
|
* @param {XMLHttpRequest} xhr Объект запроса
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.beforeSend = function(xhr) {
|
||||||
|
xhr.setRequestHeader('X-CSRF', this._CSRF);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Скрывает форму отправки комментария
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.hideForm = function() {
|
||||||
|
this._$form.prev().prop('checked', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создаёт новый комментарий, скрывает форму, снимает прогресс.
|
||||||
|
* @param {Object} data Ответ сервера
|
||||||
|
* @param {String} textStatus Статус ответа
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.onSuccess = function(data, textStatus) {
|
||||||
|
var $textarea = this._$textarea;
|
||||||
|
|
||||||
|
if (textStatus === 'success') {
|
||||||
|
if (data.error) {
|
||||||
|
this.onError(null, null, data.error);
|
||||||
|
} else {
|
||||||
|
if (this.isRecommendation() && this._text.trim().length === 0) {
|
||||||
|
this.showSuccessRecommendation();
|
||||||
|
}/* else {
|
||||||
|
this.createComment(data);
|
||||||
|
}*/
|
||||||
|
this.hideForm();
|
||||||
|
|
||||||
|
// Cleaning textarea
|
||||||
|
$textarea.val('');
|
||||||
|
this.setProgress(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AjaxCommentProcessor.prototype.createComment = function(data) {
|
||||||
|
/* global create_comment_elements */
|
||||||
|
create_comment_elements({
|
||||||
|
id: data.comment_id,
|
||||||
|
toId: this._commentId || null,
|
||||||
|
postId: this._postId,
|
||||||
|
author: $('#name h1').text(),
|
||||||
|
text: this._text,
|
||||||
|
fadeOut: true,
|
||||||
|
isRec: this.isRecommendation()
|
||||||
|
}, this.insertComment.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Вставляет комментарий в DOM
|
||||||
|
* @param {jQuery} $comment
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.insertComment = function($comment) {
|
||||||
|
var $parentCommentChildren;
|
||||||
|
|
||||||
|
if ($('#comments #tree-switch a').eq(0).hasClass('active') || (this._commentId === undefined)) {
|
||||||
|
// Adding to the end of the list
|
||||||
|
$('.content-wrap #comments #post-reply').before($comment);
|
||||||
|
} else {
|
||||||
|
// Check for children
|
||||||
|
$parentCommentChildren = this._$post.next('.comments');
|
||||||
|
|
||||||
|
// @fixme Find a bug with lost indentation of new comment
|
||||||
|
// If child comment already exist
|
||||||
|
if ($parentCommentChildren.length) {
|
||||||
|
console.log('Child comments found. Appending...');
|
||||||
|
$parentCommentChildren.append($comment);
|
||||||
|
} else {
|
||||||
|
console.log('No child comments found. Creating...');
|
||||||
|
this._$post.after(
|
||||||
|
$('<div>')
|
||||||
|
.addClass('comments')
|
||||||
|
.append($comment)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showComment($comment);
|
||||||
|
};
|
||||||
|
|
||||||
|
AjaxCommentProcessor.prototype.showComment = function($comment) {
|
||||||
|
$('body').animate({
|
||||||
|
scrollTop: $comment.offset().top
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Показывает алерт с ошибкой и снимает прогресс, если коммент не отправился
|
||||||
|
* @param {*} req
|
||||||
|
* @param {*} status
|
||||||
|
* @param {String} error
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.onError = function(req, status, error) {
|
||||||
|
/* global alert */
|
||||||
|
alert(chrome.i18n.getMessage('msg_comment_send_failed') + '\n' + error);
|
||||||
|
|
||||||
|
this.setProgress(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Устанавливает прогресс
|
||||||
|
* @param {Boolean} isProgress true — включить прогресс, false — отключить
|
||||||
|
*/
|
||||||
|
AjaxCommentProcessor.prototype.setProgress = function(isProgress) {
|
||||||
|
this._$textarea.prop('disabled', isProgress);
|
||||||
|
this._$form.toggleClass('pp-progress', isProgress);
|
||||||
|
};
|
||||||
|
|
||||||
|
AjaxCommentProcessor.prototype.getRecommendationLink = function() {
|
||||||
|
var url = '//point.im/' + this._postId;
|
||||||
|
var text = '#' + this._postId;
|
||||||
|
|
||||||
|
if (this._commentId) {
|
||||||
|
url += '#' + this._commentId;
|
||||||
|
text += '/' + this._commentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<a href="' + url + '">' + text + '</a>';
|
||||||
|
};
|
||||||
|
|
||||||
|
AjaxCommentProcessor.prototype.showSuccessRecommendation = function() {
|
||||||
|
var $notification = $('<div>')
|
||||||
|
.addClass('pp-notification pp-notification-success');
|
||||||
|
|
||||||
|
$notification.html(this.getRecommendationLink() + ' ' + chrome.i18n.getMessage('msg_success_recommendation'));
|
||||||
|
|
||||||
|
$notification.on('transitionend', function() {
|
||||||
|
$notification.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('body').append($notification);
|
||||||
|
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
$notification.addClass('pp-fade');
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,172 @@
|
||||||
|
/**
|
||||||
|
* Подгружает картинки через сервер Никиты
|
||||||
|
* @constructor
|
||||||
|
* @param {jQuery} $links Коллекция ссылок
|
||||||
|
* @param {OptionsManager} options Опции
|
||||||
|
*/
|
||||||
|
function Booru($links, options) {
|
||||||
|
this.count = 0;
|
||||||
|
|
||||||
|
this.loadAllImages($links, options.is('option_embedding_remove_original_link'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base URL of gelbooru picture API (@NokitaKaze)
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
Booru.baseUrl = 'https://evidell.xyz/get_booru_picture.php';
|
||||||
|
|
||||||
|
/* jshint maxlen:false */
|
||||||
|
Booru.services = {
|
||||||
|
danbooru: {
|
||||||
|
mask: new RegExp('^https?://danbooru\\.donmai\\.us/posts/([0-9]+)', 'i'),
|
||||||
|
matchNumber: 1
|
||||||
|
},
|
||||||
|
gelbooru: {
|
||||||
|
mask: new RegExp('^https?\\://(www\\.)?gelbooru\\.com\\/index\\.php\\?page\\=post&s\\=view&id=([0-9]+)', 'i'),
|
||||||
|
matchNumber: 2
|
||||||
|
},
|
||||||
|
safebooru: {
|
||||||
|
mask: new RegExp('^https?\\://(www\\.)?safebooru\\.org\\/index\\.php\\?page\\=post&s\\=view&id=([0-9]+)', 'i'),
|
||||||
|
matchNumber: 2
|
||||||
|
},
|
||||||
|
deviantart: {
|
||||||
|
mask: new RegExp('^https?\\://(www\\.)?([a-z0-9-]+\\.)?deviantart\\.com\\/art/[0-9a-z-]+?\\-([0-9]+)(\\?.+)?$', 'i'),
|
||||||
|
matchNumber: 3
|
||||||
|
},
|
||||||
|
e621: {
|
||||||
|
mask: new RegExp('^https?\\://(www\\.)?e621\\.net\\/post\\/show\\/([0-9]+)\\/', 'i'),
|
||||||
|
matchNumber: 2
|
||||||
|
},
|
||||||
|
derpibooru: {
|
||||||
|
mask: new RegExp('^https?\\://derpiboo\\.ru\\/([0-9]+)', 'i'),
|
||||||
|
matchNumber: 1
|
||||||
|
},
|
||||||
|
tumblr: {
|
||||||
|
mask: new RegExp('^https?\\://([0-9a-z-]+)\\.tumblr\\.com\\/post\\/([0-9]+)', 'i'),
|
||||||
|
matchNumber: 2,
|
||||||
|
params: {
|
||||||
|
add_username: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pixiv: {
|
||||||
|
mask: new RegExp('^https?://(www\\.)?pixiv\\.net\\/member_illust\\.php\\?mode\\=medium\\&illust_id\\=([0-9]+)', 'i'),
|
||||||
|
matchNumber: 2
|
||||||
|
},
|
||||||
|
animepicturesnet: {
|
||||||
|
mask: new RegExp('^http\\:\\/\\/anime\\-pictures\\.net\\/pictures\\/view_post\\/([0-9]+)', 'i'),
|
||||||
|
matchNumber: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* jshint maxlen:120 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обрабатывает все картинки
|
||||||
|
* @param {jQuery} $links Коллекция ссылок
|
||||||
|
* @param {Boolean} removeOriginal Удалять ли оригинальную ссылку
|
||||||
|
*/
|
||||||
|
Booru.prototype.loadAllImages = function($links, removeOriginal) {
|
||||||
|
var booru = this;
|
||||||
|
|
||||||
|
$links.each(function(index, link) {
|
||||||
|
var $link = $(link);
|
||||||
|
var href = link.href;
|
||||||
|
var $image;
|
||||||
|
|
||||||
|
if ($link.hasClass('booru_pic')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(booru.constructor.services).some(function(service) {
|
||||||
|
$image = booru.createImageFromService(service, href);
|
||||||
|
|
||||||
|
return $image;
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($image) {
|
||||||
|
$link.before($image);
|
||||||
|
this.count++;
|
||||||
|
|
||||||
|
if (removeOriginal) {
|
||||||
|
$link.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создаёт картинку исходя из сервиса, если адрес картинки матчится
|
||||||
|
* @param {String} service Идентификатор сервиса
|
||||||
|
* @param {String} href URL картинки (который вставлен в пост)
|
||||||
|
*/
|
||||||
|
Booru.prototype.createImageFromService = function(service, href) {
|
||||||
|
var serviceInfo = this.constructor.services[service];
|
||||||
|
var matches = href.match(serviceInfo.mask);
|
||||||
|
var imageArgs;
|
||||||
|
var params = {};
|
||||||
|
var key;
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
imageArgs = [ service, matches[serviceInfo.matchNumber] ];
|
||||||
|
|
||||||
|
if (serviceInfo.params) {
|
||||||
|
for (key in serviceInfo.params) {
|
||||||
|
if (serviceInfo.params.hasOwnProperty(key)) {
|
||||||
|
params[key] = matches[serviceInfo.params[key]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imageArgs.push(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createImage.apply(this, imageArgs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создаёт ссылку с картикной
|
||||||
|
* @param {String} service Ключевое имя сервиса для Никиты
|
||||||
|
* @param {String} id Идентификатор картинки
|
||||||
|
* @param {Object} [params] Дополнительные параметры, которые надо добавить в url
|
||||||
|
* @returns {jQuery} Элемент ссылки
|
||||||
|
*/
|
||||||
|
Booru.prototype.createImage = function(service, id, params) {
|
||||||
|
var $link = $('<a>');
|
||||||
|
var $img = $('<img>');
|
||||||
|
var title = service + ' image #' + id;
|
||||||
|
var imageSource = this.getImageLink(service, id, params);
|
||||||
|
|
||||||
|
$link
|
||||||
|
.addClass('booru_pic')
|
||||||
|
.addClass('booru-' + service + '-' + id)
|
||||||
|
.addClass('postimg')
|
||||||
|
.attr({
|
||||||
|
href: imageSource,
|
||||||
|
id: 'booru_pic_' + this.count,
|
||||||
|
title: title,
|
||||||
|
target: '_blank'
|
||||||
|
});
|
||||||
|
|
||||||
|
$img.attr({
|
||||||
|
alt: title,
|
||||||
|
src: imageSource
|
||||||
|
});
|
||||||
|
|
||||||
|
$link.append($img);
|
||||||
|
|
||||||
|
return $link;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерирует ссылку на картинку
|
||||||
|
* @param {String} service Ключевое имя сервиса для Никиты
|
||||||
|
* @param {String} id Идентификатор картинки
|
||||||
|
* @param {Object} [params] Дополнительные параметры, которые надо добавить в url
|
||||||
|
* @returns {String} Ссылка на картинку
|
||||||
|
*/
|
||||||
|
Booru.prototype.getImageLink = function(service, id, params) {
|
||||||
|
return this.constructor.baseUrl + '?' + $.param($.extend({
|
||||||
|
domain: service,
|
||||||
|
id: id
|
||||||
|
}, params));
|
||||||
|
};
|
|
@ -1,8 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Point Plus options</title>
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<title data-i18n="options_page_title"></title>
|
||||||
<link rel="stylesheet" href="css/options.css" type="text/css">
|
<link rel="stylesheet" href="css/options.css" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -40,11 +40,6 @@
|
||||||
<input type="checkbox" name="option-fancybox-bind-images-to-one-flow">
|
<input type="checkbox" name="option-fancybox-bind-images-to-one-flow">
|
||||||
<span data-i18n="option_fancybox_bind_images_to_one_flow"></span>
|
<span data-i18n="option_fancybox_bind_images_to_one_flow"></span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="option-node">
|
|
||||||
<input type="checkbox" name="option-fancybox-smart-hints">
|
|
||||||
<span data-i18n="option_fancybox_smart_hints"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="option-node">
|
<label class="option-node">
|
||||||
|
@ -75,62 +70,42 @@
|
||||||
<span data-i18n="option_videos_parse_all_links"></span>
|
<span data-i18n="option_videos_parse_all_links"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="option-node">
|
|
||||||
<input type="checkbox" name="option-videos-parse-leave-links">
|
|
||||||
<span data-i18n="option_videos_parse_leave_links"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="option-node">
|
|
||||||
<input type="checkbox" name="option-audios-parse-links" id="option-audios-parse-links">
|
|
||||||
<label for="option-audios-parse-links" data-i18n="option_audios_parse_links"></label>
|
|
||||||
|
|
||||||
<label class="option-node">
|
<label class="option-node">
|
||||||
<input type="checkbox" name="option-audios-parse-leave-links">
|
<input type="checkbox" name="option-audios-parse-links">
|
||||||
<span data-i18n="option_embedding_soundcloud_orig_link"></span>
|
<span data-i18n="option_audios_parse_links"></span>
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="option-node">
|
|
||||||
<input type="checkbox" name="option-embedding-soundcloud" id="option-embedding-soundcloud">
|
|
||||||
<label for="option-embedding-soundcloud" data-i18n="option_embedding_soundcloud"></label>
|
|
||||||
|
|
||||||
<label class="option-node">
|
|
||||||
<input type="checkbox" name="option-embedding-soundcloud-orig-link">
|
|
||||||
<span data-i18n="option_embedding_soundcloud_orig_link"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="option-node">
|
|
||||||
<input type="checkbox" name="option-embedding-pleercom" id="option-embedding-pleercom">
|
|
||||||
<label for="option-embedding-pleercom" data-i18n="option_embedding_pleercom"></label>
|
|
||||||
|
|
||||||
<label class="option-node">
|
|
||||||
<input type="checkbox" name="option-embedding-pleercom-nokita-server">
|
|
||||||
<span data-i18n="option_embedding_pleercom_nokita_server"></span>
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="option-node">
|
<label class="option-node">
|
||||||
<input type="checkbox" name="option-embedding-pleercom-orig-link">
|
<input type="checkbox" name="option-embedding-soundcloud">
|
||||||
<span data-i18n="option_embedding_soundcloud_orig_link"></span>
|
<span data-i18n="option_embedding_soundcloud"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="option-node">
|
|
||||||
<input type="checkbox" name="option-embedding-coubcom" id="option-embedding-coubcom">
|
|
||||||
<label for="option-embedding-coubcom" data-i18n="option_embedding_coubcom"></label>
|
|
||||||
|
|
||||||
<label class="option-node">
|
<label class="option-node">
|
||||||
<input type="checkbox" name="option-embedding-coubcom-orig-link">
|
<input type="checkbox" name="option-embedding-pleercom">
|
||||||
<span data-i18n="option_embedding_coubcom_orig_link"></span>
|
<span data-i18n="option_embedding_pleercom"></span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-embedding-coubcom">
|
||||||
|
<span data-i18n="option_embedding_coubcom"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
|
||||||
|
|
||||||
<label class="option-node">
|
<label class="option-node">
|
||||||
<input type="checkbox" name="option-embedding-twitter-tweets">
|
<input type="checkbox" name="option-embedding-twitter-tweets">
|
||||||
<span data-i18n="option_embedding_twitter_tweets"></span>
|
<span data-i18n="option_embedding_twitter_tweets"></span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-embedding-instagram-posts">
|
||||||
|
<span data-i18n="option_embedding_instagram_posts"></span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-embedding-remove-original-link">
|
||||||
|
<span data-i18n="option_embedding_remove_original_link">
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="option-node">
|
<div class="option-node">
|
||||||
|
@ -175,6 +150,16 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="option-node">
|
||||||
|
<input type="checkbox" name="option-right-panel" id="option-right-panel">
|
||||||
|
<label for="option-right-panel" data-i18n="option_right_panel"></label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-right-panel-to-unread">
|
||||||
|
<span data-i18n="option_right_panel_to_unread"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<label class="option-node">
|
<label class="option-node">
|
||||||
<input type="checkbox" name="option-fluid-layout">
|
<input type="checkbox" name="option-fluid-layout">
|
||||||
<span data-i18n="option_fluid_layout"></span>
|
<span data-i18n="option_fluid_layout"></span>
|
||||||
|
@ -246,6 +231,21 @@
|
||||||
<input type="checkbox" name="option-other-comments-user-system">
|
<input type="checkbox" name="option-other-comments-user-system">
|
||||||
<span data-i18n="option_other_comments_user_system"></span>
|
<span data-i18n="option_other_comments_user_system"></span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-other-move-all-to-menu">
|
||||||
|
<span data-i18n="option_other_move_all_to_menu"></span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-other-remove-fucking-button">
|
||||||
|
<span data-i18n="option_other_remove_fucking_button"></span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="option-node">
|
||||||
|
<input type="checkbox" name="option-other-post-draft-save">
|
||||||
|
<span data-i18n="option_other_post_draft_save"></span>
|
||||||
|
</label>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="tabs-content-item" id="websocket">
|
<section class="tabs-content-item" id="websocket">
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
|
|
||||||
auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
|
|
||||||
auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
|
|
||||||
auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
|
|
||||||
auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false
|
|
||||||
auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css
|
|
||||||
auxiliary.org-netbeans-modules-javascript2-requirejs.enabled=false
|
|
||||||
auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=node_modules/bower/node_modules/inquirer/node_modules/rx/src/core/linq/observable
|
|
||||||
browser.autorefresh.Chrome.INTEGRATED=true
|
|
||||||
browser.highlightselection.Chrome.INTEGRATED=true
|
|
||||||
config.folder=
|
|
||||||
file.reference.src-chrome_point_plus=.
|
|
||||||
files.encoding=UTF-8
|
|
||||||
grunt.action.build=
|
|
||||||
site.root.folder=${file.reference.src-chrome_point_plus}
|
|
||||||
start.file=chrome_point_plus/options.html
|
|
||||||
test.folder=
|
|
||||||
web.context.root=/file:///chrome_point_plus
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
|
||||||
<type>org.netbeans.modules.web.clientproject</type>
|
|
||||||
<configuration>
|
|
||||||
<data xmlns="http://www.netbeans.org/ns/clientside-project/1">
|
|
||||||
<name>chrome_point_plus</name>
|
|
||||||
</data>
|
|
||||||
</configuration>
|
|
||||||
</project>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
BROWSER_BINARY=$1
|
||||||
|
PATH_EXTENSION=$2
|
||||||
|
PATH_KEY=$3
|
||||||
|
|
||||||
|
echo "Packing extension using $BROWSER_BINARY and key from $PATH_KEY"
|
||||||
|
#echo "$BROWSER_BINARY --pack-extension=$PATH_EXTENSION --pack-extension-key=$PATH_KEY"
|
||||||
|
eval "$BROWSER_BINARY --pack-extension=$PATH_EXTENSION --pack-extension-key=$PATH_KEY"
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
zip -9 -r chrome_point_plus.zip chrome_point_plus
|
12
package.json
|
@ -1,10 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "chrome-point-plus",
|
"name": "chrome-point-plus",
|
||||||
"version": "1.35.1",
|
"version": "1.42.1",
|
||||||
"description": "Chrome extension for point.im",
|
"description": "Chrome extension for point.im",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"postinstall": "./node_modules/.bin/bower install && grunt",
|
||||||
|
"lint": "./node_modules/.bin/jshint . && ./node_modules/.bin/jscs .",
|
||||||
|
"test": "npm run lint"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -15,7 +17,9 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bower": "^1.3.12",
|
"bower": "^1.3.12",
|
||||||
"grunt": "^0.4.5",
|
"grunt": "^0.4.5",
|
||||||
"grunt-bump": "git://github.com/nkirkes/grunt-bump.git#nkirkes/restrict-version-key-name",
|
"grunt-bump": "^0.3.0",
|
||||||
"grunt-contrib-copy": "^0.7.0"
|
"grunt-contrib-copy": "^0.7.0",
|
||||||
|
"jscs": "^1.10.0",
|
||||||
|
"jshint": "^2.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|