Compare commits

...

137 Commits

Author SHA1 Message Date
Alexey Skobkin 787d5b1c37 Release 1.42.1 2016-08-19 18:05:31 +03:00
Alexey Skobkin 58a38460f9 Booru images API base URL changed. 2016-08-19 18:03:17 +03:00
Alexey Skobkin 02c0594509 Release 1.42.0 2016-05-15 23:42:39 +03:00
Alexey Skobkin 552e65520d jQuery updated to version 3. 2016-05-15 23:40:56 +03:00
Alexey Skobkin af6cf59fdd Some scripts for building extension package. 2016-05-15 23:05:22 +03:00
Alexey Skobkin 7fcbc7c039 Release 1.41.1 2016-05-15 22:19:56 +03:00
Alexey Skobkin fe15a1633f update_right_panel_unread_count() bug fix. Now it counts comments on any tree level. 2016-05-15 22:19:46 +03:00
Alexey Skobkin 07b6a8d8bf Release 1.41.0 2016-05-15 16:31:23 +03:00
Alexey Skobkin afee3205dc Option "option_fancybox_smart_hints" removed. 2016-05-15 16:31:04 +03:00
Alexey Skobkin 0674268548 Some refactoring and optimizations. 2016-05-15 16:07:59 +03:00
Alexey Skobkin be749ff31f Release 1.40.4 2016-05-13 03:56:48 +03:00
Alexey Skobkin 207dff9e67 "Move /all button" fix and minor refactoring. 2016-05-13 03:56:34 +03:00
Alexey Skobkin b2fc048450 Release 1.40.3 2016-05-10 22:11:47 +03:00
Alexey Skobkin a771b26952 Updating comments count on WebSocket comment message. 2016-05-10 22:11:41 +03:00
Alexey Skobkin 2fc1134124 Release 1.40.2 2016-05-10 01:22:47 +03:00
Alexey Skobkin 6ee91fbb25 #78 fixed. Null recomendations comments fixed. WS close messages in console. 2016-05-10 01:22:43 +03:00
Alexey Skobkin 072ece28cd Do not "Go to new comment" button outside of the post page. 2016-05-10 00:49:46 +03:00
Alexey Skobkin e7a48b467f Release 1.40.1 2016-05-10 00:42:19 +03:00
Alexey Skobkin 0ba765e181 #95 fixed. 2016-05-10 00:42:16 +03:00
Alexey Skobkin 8f75c8d315 Release 1.40.0 2016-05-10 00:31:54 +03:00
Alexey Skobkin e67eb36443 Sidebar "go to unread comment" button bugfix. "Remove the fucking button" option added. 2016-05-10 00:31:50 +03:00
Alexey Skobkin ffef920411 Release 1.39.0 2016-05-09 04:56:56 +03:00
Alexey Skobkin 99760d2eb7 #97 done. Side panel with "Go to new comment" button. 2016-05-09 04:56:51 +03:00
Alexey Skobkin dc58ac8532 Release 1.38.0 2016-05-09 03:33:35 +03:00
Alexey Skobkin f91dfc4ba7 #96 and some other fixed. Now inserting new comments as HTML (new WebSocket message format). 2016-05-09 03:33:31 +03:00
Alexey Skobkin 75bc6636b2 Release 1.37.1 2016-05-09 03:18:30 +03:00
Alexey Skobkin eecd3133b8 #98 fixed. Adding new comments with 'unread' class. 2016-05-09 03:18:24 +03:00
Alexey Skobkin 06682d3222 Release 1.37.0 2016-05-09 02:52:49 +03:00
Alexey Skobkin 6c286150fa nbproject removed. 2016-05-09 02:47:08 +03:00
Alexey Skobkin 1df716d694 #102 done. Move /all page link to left menu. 2016-05-09 02:42:51 +03:00
Alexey Skobkin 7715c43ba1 Release 1.36.3 2015-07-19 22:55:26 +03:00
Alexey Skobkin 465c10137e Duplicate comments quick fix. 2015-07-19 22:47:09 +03:00
Alexey Skobkin a3a82d6087 nbproject removed. IDEA project added to .gitignore. 2015-07-19 22:22:29 +03:00
isqua b2d1bfdf4a Update grunt-bump version 2015-02-22 14:53:47 +03:00
Alexey Skobkin cc647700f0 Merged in remove_innerhtml (pull request #48) Remove unnecessary html inserting 2015-02-12 20:02:00 +03:00
isqua e865c41504 Remove unnecessary html inserting 2015-02-11 14:16:28 +03:00
Alexey Skobkin a64719424d Release 1.36.2 2015-02-10 22:22:06 +03:00
Alexey Skobkin 643919c62f Popup moved to the bottom. 2015-02-10 22:19:06 +03:00
Alexey Skobkin 11b1338841 Merged in iss87 (pull request #47) Улучшить аяксовые рекоммендации 2015-02-10 19:47:01 +03:00
isqua af70f93ec0 Показывать уведомление при успешной рекомендации без комментария; Fixes #86 2015-02-08 22:04:36 +03:00
isqua d45df7d629 Вставлять собственный комментарий-рекомендацию как комментарий-рекомендацию; Fixes #85 2015-02-08 22:04:12 +03:00
isqua 4e6d09a774 Поменять url для рекомендации комментария; Fixes #87 2015-02-08 22:03:52 +03:00
Alexey Skobkin 0bea1baa24 Release 1.36.1 2015-02-08 19:37:34 +03:00
Alexey Skobkin 2a0546fd65 Merged in iss84 (pull request #46) Не проверять файлы, если поля аттача нет; Fixes #84 2015-02-08 19:03:11 +03:00
isqua 0089798f86 Не проверять файлы, если поля аттача нет 2015-02-08 17:01:56 +03:00
Alexey Skobkin 2d98767bdd Merge branch 'master' of bitbucket.org:skobkin/chrome_point_plus 2015-02-08 13:44:15 +03:00
Alexey Skobkin 25fc9af6fa Release 1.36.0 2015-02-08 13:42:23 +03:00
Alexey Skobkin 4f7fc33cbd Fix fancybox missing images. Garbage deleted. 2015-02-08 13:39:39 +03:00
isqua 9d012c676f Replace Никита with NokitaKaze 2015-02-08 13:13:49 +03:00
isqua 7b4e3f250a Merged in iss83 (pull request #44)
Показывать добавленный комментарий; Fixes #83
2015-02-07 20:49:25 +03:00
isqua 35b1a2c309 Открывать пост и комментарий, если комментарий отправлен не со страницы поста 2015-02-07 20:27:19 +03:00
isqua 00846a56cc Скроллить к добавленному комментарию на странице поста 2015-02-07 20:27:19 +03:00
isqua 62e20aca51 Merged in options_top_elem_fix (pull request #45)
Поправить нецеликом нажимающийся верхний пункт
2015-02-07 20:26:30 +03:00
isqua a9a879b273 Поправить нецеликом нажимающийся верхний пункт 2015-02-07 20:25:51 +03:00
isqua 4615113a44 Merged in iss81 (pull request #43)
Отправлять форму не аяксом, если выбран файл; Fixes #81
2015-02-07 20:16:07 +03:00
isqua 5faabf04bd Отправлять форму не аяксом, если выбран файл 2015-02-07 19:38:11 +03:00
isqua ec6eb34e22 Не добавлять комментарий, если с сервера пришло {"error":"SomeError"} 2015-02-07 19:38:11 +03:00
isqua ad5ace57cb Merged in isqua/chrome_point_plus/iss82 (pull request #42)
Починить рекомендацию постов и комментариев при ajax-комментах; Fixes #82
2015-02-07 19:37:40 +03:00
isqua 94846f28f3 Починить рекомендацию постов и комментариев при ajax-комментах 2015-02-07 18:17:49 +03:00
isqua 13ee04dcc2 Merged in isqua/chrome_point_plus/ajax_comments (pull request #41)
Вынести ajax-комментарии, добавить биндинг на отправку формы
2015-02-07 00:21:04 +03:00
isqua a5accb5be3 Вынести ajax-комментарии, добавить биндинг на отправку формы 2015-02-05 22:48:13 +03:00
isqua 6b7df230b6 Merged in isqua/chrome_point_plus/iss80 (pull request #40)
AJAX comment sending indictaion; Fixes #80
2015-02-05 20:51:47 +03:00
isqua 639b72620b AJAX comment sending indictaion 2015-02-04 13:58:03 +03:00
isqua 74c0e0319f Merged in isqua/chrome_point_plus/code-style (pull request #14)
Code style checking
2015-02-04 13:56:19 +03:00
isqua 0a2b4c7538 Add info about build to README 2015-02-04 13:54:33 +03:00
isqua bd2aa28afc Fix codestyle in options.js 2015-02-03 19:07:22 +03:00
isqua 98982c6145 Fix codestyle in background.js 2015-02-03 19:07:22 +03:00
isqua 82b88b2146 Add jscs config 2015-02-03 19:07:22 +03:00
isqua 2af04fb767 Add jshint configs 2015-02-03 19:07:22 +03:00
isqua eb32411fa7 Add jshint and jscs 2015-02-03 19:07:22 +03:00
isqua 81ad370af1 Merged in isqua/chrome_point_plus/refactor_booru (pull request #39)
Refactor embedding from booru, tumblr etc.
2015-02-03 19:04:40 +03:00
isqua 358d44b3bd Add info about Nokita server to options 2015-02-02 14:47:58 +03:00
isqua 795298c94f Refactor embedding from booru, tumblr etc. 2015-02-02 14:47:57 +03:00
Alexey Skobkin f8e573a8b5 Merged in isqua/chrome_point_plus/combine_embedding_remove_link (pull request #38) Replace all “don’t remove original link” with single “remove original link” option 2015-01-31 15:30:13 +03:00
isqua fe6381ccfd Add chevron to video embedding option 2015-01-31 15:12:50 +03:00
isqua 18e75842f8 Remove video original link option 2015-01-31 15:12:50 +03:00
isqua a2f6aab453 Remove audio, soundclound and pleer.com original link option 2015-01-31 15:11:56 +03:00
isqua 82c2ef8442 Remove coub original link option 2015-01-31 15:11:56 +03:00
isqua fad1e5e689 Remove instagram original link option 2015-01-31 15:11:56 +03:00
isqua cb7cb397c1 Add single option `Remove original link` 2015-01-31 15:11:17 +03:00
Alexey Skobkin d35dc6036e Merged in isqua/chrome_point_plus/refactor_prostopleer (pull request #37) Refactor pleer.com and instagram embedding, remove bquery_ajax; Fixes #79 2015-01-31 14:49:09 +03:00
isqua 1f97b6d19c Remove bquery_ajax 2015-01-31 14:41:33 +03:00
isqua 0f9cb4e167 Refactor instagram embedding 2015-01-31 14:41:32 +03:00
isqua 08fa6c7bfa Remove pleercom_nokita_server option 2015-01-31 14:41:32 +03:00
isqua 21cab163d5 Refactor pleer.com embedding 2015-01-31 14:41:32 +03:00
Alexey Skobkin 068c461070 Merged in isqua/chrome_point_plus/iss74 (pull request #35) String option type; Fixes #74 2015-01-31 14:41:04 +03:00
isqua 54966185d1 Добавить текстовый тип опций 2015-01-31 11:54:54 +03:00
isqua fa02bd8f7b Переименовать объкет Options в OptionsPage во избежание путаницы 2015-01-31 11:54:54 +03:00
Alexey Skobkin 5f88797a93 Merged in isqua/chrome_point_plus/refactor_unique_comments (pull request #36) Remove bquery_ajax from unique comments counter 2015-01-31 08:34:33 +03:00
Alexey Skobkin 62673d3790 Merged in merge_pr25 (pull request #34) Instagram, drafts, some fixes. 2015-01-31 08:20:24 +03:00
Alexey Skobkin eb6b67f612 Some fixes. 2015-01-31 08:10:54 +03:00
isqua 13aa8595e7 Remove bquery_ajax from unique comments counter 2015-01-29 14:23:42 +03:00
Alexey Skobkin d818c7dc66 Fix bug #11. WebSocket recommendation comments. 2015-01-27 05:43:20 +03:00
Alexey Skobkin 6a951ea8d3 Fix bug #17. "@" on the subscribers and subscriptions page. 2015-01-27 04:36:02 +03:00
Alexey Skobkin f7d399c41a i18n for options page title. 2015-01-27 04:10:13 +03:00
Alexey Skobkin 3e6e3d5855 Space key fix from pull request #25. 2015-01-27 04:02:48 +03:00
Alexey Skobkin aa7b9649d1 Twitter fix. 2015-01-27 03:59:05 +03:00
Alexey Skobkin 684f6c15fe Post draft saving with option and some optimization. 2015-01-27 03:55:15 +03:00
Alexey Skobkin 429c432dc5 Встраивание Instagram из pull request #25. 2015-01-27 02:55:15 +03:00
Alexey Skobkin afa1ef0fb0 Merged in isqua/chrome_point_plus/oop_messages (pull request #28) Create objects for CSS and JS injections and for Message Handler 2015-01-27 00:30:57 +03:00
isqua 633410061a Add MessageSender module 2015-01-21 17:24:41 +03:00
isqua 49328a4b4a Refactor background.js 2015-01-21 17:24:41 +03:00
isqua 4a8d6f49f4 Move OptionsManager to separate file 2015-01-21 17:24:41 +03:00
Alexey Skobkin d90ebd48f3 Merge branch 'master' of bitbucket.org:skobkin/chrome_point_plus 2015-01-21 17:22:01 +03:00
isqua 552b997ba3 Merged in isqua/chrome_point_plus/nested_level_img_fix (pull request #33)
Исправить покусанные кружки
2015-01-21 17:10:32 +03:00
isqua b7768ca8a9 Заменить PNG-точечки на SVG 2015-01-20 15:14:32 +03:00
isqua 26893fbb4f Исправить обрезанные кружки при резиновой вёрстке 2015-01-20 15:12:26 +03:00
Alexey Skobkin 0eca347c7d Release 1.35.1 2015-01-20 12:19:41 +04:00
Alexey Skobkin 9bf72cbeb0 Release 1.35.0 2015-01-20 12:02:07 +04:00
Alexey Skobkin 5d3e09d99c Fadeout fix. 2015-01-20 11:51:46 +04:00
Alexey Skobkin 2fb3dca119 Merged in feature_ajax_comments (pull request #32) Отправка комментариев через AJAX 2015-01-20 10:49:00 +03:00
Alexey Skobkin 454976daa7 Garbage removed. 2015-01-20 11:33:14 +04:00
Alexey Skobkin e30b440956 Merge branch 'master' into feature_ajax_comments 2015-01-20 10:23:59 +03:00
Alexey Skobkin 60d5a7351e Merged in isqua/chrome_point_plus/nesting_level_indicator (pull request #31)
Не добавлять лишний элемент для отрисовки точечек и не портить марджины
2015-01-20 10:13:23 +03:00
isqua 46c430a3d8 Не добавлять лишний элемент для отрисовки точечек и не портить марджины 2015-01-19 23:01:02 +03:00
Alexey Skobkin 612052e5ca Posts notification option check fix. 2015-01-16 15:48:57 +04:00
Alexey Skobkin 4203ba62ed First! 2015-01-15 18:37:28 +04:00
Alexey Skobkin 2a5e9da2d8 New options for WebSocket post processing. 2015-01-15 15:19:12 +04:00
Alexey Skobkin 6d6a9fa3d6 Option for AJAX comments. A bit of JSDoc. 2015-01-15 13:45:07 +04:00
Alexey Skobkin 56bd3117ec Error messages. 2015-01-15 13:05:37 +04:00
Alexey Skobkin c5ba450afe Ajax comments test implementation. Some bugs included. 2015-01-14 18:41:34 +04:00
Alexey Skobkin dcb1dcf529 Notification click bugfix. 2015-01-14 15:42:20 +04:00
Alexey Skobkin 26b5da4e93 Fixes. 2015-01-14 14:59:51 +04:00
Alexey Skobkin fadfc43aa1 Comment DOM generation moved to separate function. Some bugs fixed. Some optimizations done. 2015-01-14 13:34:04 +04:00
Alexey Skobkin b49ecaf937 Locale fixes. 2015-01-14 09:30:40 +04:00
Alexey Skobkin 01387be169 Merge branch 'master' of bitbucket.org:skobkin/chrome_point_plus 2015-01-14 08:16:06 +03:00
Alexey Skobkin c4e6683c80 nbproject 2015-01-14 08:15:52 +03:00
isqua 1a190e04e8 Fix “enlarge font” settings 2015-01-14 08:01:45 +03:00
isqua bf9e8940ed Fixes #58; grunt-bump breaks manifest_version in manifest.json 2015-01-14 08:01:45 +03:00
Alexey Skobkin 62e357dad6 jquery idTabs dropped. 2015-01-14 08:52:04 +04:00
Alexey Skobkin 1b5cd3ce97 Merged in isqua/chrome_point_plus/iss61 (pull request #29) Fixes #61; Fix “enlarge font” settings 2015-01-11 16:53:14 +03:00
isqua 338fd8682a Fix “enlarge font” settings 2015-01-11 14:17:59 +03:00
Alexey Skobkin f12cdc0b9f Merged in isqua/chrome_point_plus/grut-bump_fork (pull request #26) Fixes #58; grunt-bump breaks manifest_version in manifest.json 2015-01-08 23:08:29 +03:00
Alexey Skobkin ffc6ce084b Merged in isqua/chrome_point_plus/editorconfig (pull request #27) Add editorconfig and replace all CRLF with LF 2015-01-08 22:28:13 +03:00
isqua aabd83881a Replace CLRF with LF and add new line to the end of files 2015-01-08 17:41:12 +03:00
isqua 08a94616cc Add editorconfig 2015-01-08 16:19:25 +03:00
isqua 23dcf17f3f Fixes #58; grunt-bump breaks manifest_version in manifest.json 2015-01-08 15:34:32 +03:00
44 changed files with 3226 additions and 2400 deletions

12
.editorconfig Normal file
View File

@ -0,0 +1,12 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
[{package.json,bower.json}]
indent_size = 2

4
.gitignore vendored
View File

@ -1,5 +1,7 @@
chrome_point_plus/vendor/
/nbproject/private/
/nbproject/
node_modules/
npm-debug.log
publish
vendor/
/.idea/

119
.jscs.json Normal file
View File

@ -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/**"
]
}

9
.jshintignore Normal file
View File

@ -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/**

26
.jshintrc Normal file
View File

@ -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
}
}

View File

@ -1,5 +1,5 @@
var vendorCopy = [
'jquery/jquery.min.js',
'jquery/dist/jquery.min.js',
'fancybox/source/jquery.fancybox.pack.js',
'fancybox/source/helpers/jquery.fancybox-media.js',
@ -18,12 +18,15 @@ var vendorCopy = [
vendorCopy.push({
expand: true,
src: [ 'vendor/fancybox/source/*.png' ],
src: [
'vendor/fancybox/source/*.png',
'vendor/fancybox/source/*.gif'
],
dest: 'chrome_point_plus/'
});
/* global module */
module.exports = function(grunt) {
// Настройки
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
@ -46,7 +49,7 @@ module.exports = function(grunt) {
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
globalReplace: true
}
},
}
});
// Загрузить плагины

View File

@ -1,21 +1,21 @@
The MIT License (MIT), reference http://www.opensource.org/licenses/mit-license.php
Copyright (c) 2014 Alexey Skobkin <skobkin-ru@ya.ru>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
The MIT License (MIT), reference http://www.opensource.org/licenses/mit-license.php
Copyright (c) 2014 Alexey Skobkin <skobkin-ru@ya.ru>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,30 +1,63 @@
# README #
Коротенькое пояснение what the fuck is going on.
### Что это за репозиторий? ###
В данном репозитории располагаются исходные коды расширения Point+, которое предназначено для расширения функциональности сайта [Point.im](https://point.im/).
### Как заставить его работать? ###
Есть несколько вариантов. Выбирайте на свой вкус:
* Установить расширение из [репозитория Opera addons](https://addons.opera.com/en/extensions/details/point/?display=en)
* Установить расширение из [репозитория Google Chrome Extensions](https://chrome.google.com/webstore/detail/point%2B/ghaddonhnchkdjaciggjijhophciboam?hl=ru)
* Установить расширение из [раздела Downloads на Bitbucket](https://bitbucket.org/skobkin/chrome_point_plus/downloads) (*.nex - Opera, *.crx - Chrome)
* Собрать самостоятельно из исходников ([Chrome](https://developer.chrome.com/extensions/packaging), [Opera](https://dev.opera.com/extensions/tut_basics.html))
### Как настраивать? ###
В адресной строке (омнибокс) появится иконка Point.im. Если на нёё нажать - появится окошко настроек.
![Настройки расширения](https://storage4.static.itmages.ru/i/15/0107/h_1420652338_6632200_307d80b672.png "Окно настроек расширения")
### Хочу помочь, ШТОДЕЛОЦ? ###
* Писать мне [в поинте](https://skobkin-ru.point.im/) или [куда-нибудь ещё](https://skobk.in/contacts/)
* Сразу присылать пулл-реквесты с шашкой наголо
* Поставить в магазинах Opera и Chrome оценку расширению
* Задонатить (см. таб Feedback в настройках)
# README #
Коротенькое пояснение what the fuck is going on.
### Что это за репозиторий? ###
В данном репозитории располагаются исходные коды расширения Point+, которое предназначено для расширения функциональности сайта [Point.im](https://point.im/).
### Как заставить его работать? ###
Есть несколько вариантов. Выбирайте на свой вкус:
* Установить расширение из [репозитория Opera addons](https://addons.opera.com/en/extensions/details/point/?display=en)
* Установить расширение из [репозитория Google Chrome Extensions](https://chrome.google.com/webstore/detail/point%2B/ghaddonhnchkdjaciggjijhophciboam?hl=ru)
* Установить расширение из [раздела Downloads на Bitbucket](https://bitbucket.org/skobkin/chrome_point_plus/downloads) (*.nex - Opera, *.crx - Chrome)
* Собрать самостоятельно из исходников ([Chrome](https://developer.chrome.com/extensions/packaging), [Opera](https://dev.opera.com/extensions/tut_basics.html))
### Как настраивать? ###
В адресной строке (омнибокс) появится иконка Point.im. Если на нёё нажать - появится окошко настроек.
![Настройки расширения](https://storage4.static.itmages.ru/i/15/0107/h_1420652338_6632200_307d80b672.png "Окно настроек расширения")
### Хочу помочь, ШТОДЕЛОЦ? ###
* Писать мне [в поинте](https://skobkin-ru.point.im/) или [куда-нибудь ещё](https://skobk.in/contacts/)
* Сразу присылать пулл-реквесты с шашкой наголо
* Поставить в магазинах Opera и Chrome оценку расширению
* Задонатить (см. таб 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
```

View File

@ -1,6 +1,6 @@
{
"name": "chrome-point-plus",
"version": "1.30.0",
"version": "1.42.1",
"authors": [
"Alexey Skobkin"
],
@ -14,7 +14,7 @@
"chrome_point_plus/vendors/**"
],
"dependencies": {
"jquery": "~1.10.1",
"jquery": "~3",
"fancybox": "~2.1.5",
"markitup": "~1.1.14",
"soundcloud": "git@github.com:soundcloud/Widget-JS-API.git"

View File

@ -6,9 +6,12 @@
"message": "Alexey Skobkin"
},
"ext_page_action_title": {
"message": "Point+ settings"
"message": "Settings"
},
"options_page_title": {
"message": "Point+ settings"
},
"options_text_saved": {
"message": "Reload page to apply changes."
@ -45,10 +48,7 @@
"message": "Use for post links"
},
"option_fancybox_bind_images_to_one_flow": {
"message": "Bind all images from fancybox to one flow"
},
"option_fancybox_smart_hints": {
"message": "Generate image caption from tags"
"message": "Bind all images to one Fancybox gallery"
},
"option_images_load_original": {
"message": "Load original images instead of thumbnails"
@ -57,13 +57,13 @@
"message": "Enable embedding &#9660;"
},
"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": {
"message": "Audio direct links"
"message": "Audio from direct links"
},
"option_videos_parse_links": {
"message": "Video direct links"
"message": "Video from direct links &#9660;"
},
"option_videos_parse_webm": {
"message": "Only webm"
@ -71,30 +71,24 @@
"option_videos_parse_all_links": {
"message": "Parse all links"
},
"option_videos_parse_leave_links": {
"message": "Leave original link"
},
"option_embedding_soundcloud": {
"message": "Soundcloud &#9660;"
},
"option_embedding_soundcloud_orig_link": {
"message": "Leave original link"
"message": "Soundcloud"
},
"option_embedding_pleercom": {
"message": "Pleer.com &#9660;"
},
"option_embedding_pleercom_nokita_server": {
"message": "Use Nokita's server (deprecated)"
"message": "Pleer.com"
},
"option_embedding_coubcom": {
"message": "Coub.com &#9660;"
},
"option_embedding_coubcom_orig_link": {
"message": "Leave original link"
"message": "Coub.com"
},
"option_embedding_twitter_tweets": {
"message": "Twitter"
},
"option_embedding_instagram_posts": {
"message": "Instagram"
},
"option_embedding_remove_original_link": {
"message": "Remove original link"
},
"option_nsfw": {
"message": "NSFW content filtering"
},
@ -113,8 +107,17 @@
"option_nsfw_blur_comments_entire": {
"message": "Blur entire comments in nsfw posts"
},
"option_ctrl_enter": {
"message": "Send post and comments by CTRL+Enter (deprecated)"
"option_ajax": {
"message": "AJAX"
},
"option_ajax_comments": {
"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": {
"message": "Fluid layout"
@ -137,14 +140,14 @@
"option_ws_comments_notifications": {
"message": "Show desktop notifications"
},
"option_ws_feeds": {
"message": "Process feeds &#9660;"
"option_ws_posts": {
"message": "Process posts &#9660;"
},
"option_ws_feeds_subscriptions": {
"message": "Subscriptions feed"
"option_ws_posts_add": {
"message": "Add posts to the feed"
},
"option_ws_feeds_blogs": {
"message": "User blog pages (only when subscribed)"
"option_ws_posts_notifications": {
"message": "Show desktop notifications"
},
"option_enlarge_font": {
"message": "Enlarge font size &#9660;"
@ -169,13 +172,33 @@
"message": "Your hints about users"
},
"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":{
"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": {
"message": "<p>If you find an error do not hesitate to <a href=\"https:\/\/bitbucket.org\/skobkin\/chrome_point_plus\/issues?status=new&status=open\" target=\"_blank\">send me a bug report<\/a>.<\/p><p>Also you can make a donation in the following ways:<\/p><p><iframe frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" src=\"https:\/\/money.yandex.ru\/embed\/small.xml?account=41001539215836&quickpay=small&yamoney-payment-type=on&button-text=04&button-size=s&button-color=black&targets=Point%2B&default-sum=150&successURL=https%3A%2F%2Fbitbucket.org%2Fskobkin%2Fchrome_point_plus\" width=\"158\" height=\"31\"><\/p><p><\/iframe><\/p><p><iframe frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" src=\"https:\/\/money.yandex.ru\/embed\/small.xml?account=41001539215836&quickpay=small&any-card-payment-type=on&button-text=04&button-size=s&button-color=black&targets=Point%2B&default-sum=150&successURL=https%3A%2F%2Fbitbucket.org%2Fskobkin%2Fchrome_point_plus\" width=\"158\" height=\"31\"><\/iframe><\/p><p><form action=\"https:\/\/www.paypal.com\/cgi-bin\/webscr\" method=\"post\" target=\"_top\"><input type=\"hidden\" name=\"cmd\" value=\"_s-xclick\"><input type=\"hidden\" name=\"hosted_button_id\" value=\"RCW5V6UFXYTRE\"><input type=\"image\" src=\"https:\/\/www.paypalobjects.com\/ru_RU\/RU\/i\/btn\/btn_donateCC_LG.gif\" border=\"0\" name=\"submit\" alt=\"PayPal — более безопасный и легкий способ оплаты через Интернет!\"><img alt=\"\" border=\"0\" src=\"https:\/\/www.paypalobjects.com\/en_US\/i\/scr\/pixel.gif\" width=\"1\" height=\"1\"><\/form><\/p>"
},
"msg_comment_send_failed":{
"message": "Comment send error:"
},
"msg_saving_post_draft":{
"message": "Saving the post..."
},
"msg_success_recommendation": {
"message": "is recommended"
}
}

View File

@ -6,9 +6,12 @@
"message": "Алексей Скобкин"
},
"ext_page_action_title": {
"message": "Настройки Point+"
"message": "Настройки"
},
"options_page_title": {
"message": "Настройки Point+"
},
"options_text_saved": {
"message": "Для применения изменений перезагрузите страницу."
@ -45,10 +48,7 @@
"message": "Использовать для ссылок на посты"
},
"option_fancybox_bind_images_to_one_flow": {
"message": "Связать все картинки в одну галерею"
},
"option_fancybox_smart_hints": {
"message": "Генерировать подписи к картинкам из тегов"
"message": "Связать все картинки в одну галерею Fancybox"
},
"option_images_load_original": {
"message": "Загружать оригиналы вместо миниатюр"
@ -57,13 +57,13 @@
"message": "Включить встраивание &#9660;"
},
"option_images_load_booru": {
"message": "Загружать картинки с Booru, Tumblr и т.п."
"message": "Загружать картинки с Booru, Tumblr и т.п. через сервер @NokitaKaze"
},
"option_audios_parse_links": {
"message": "Прямые ссылки на аудио"
"message": "Аудио по прямой ссылке"
},
"option_videos_parse_links": {
"message": "Прямые ссылки на видео"
"message": "Видео по прямой ссылке &#9660;"
},
"option_videos_parse_webm": {
"message": "Только webm"
@ -71,30 +71,24 @@
"option_videos_parse_all_links": {
"message": "Все ссылки на видео"
},
"option_videos_parse_leave_links": {
"message": "Оставлять ссылку на видео"
},
"option_embedding_soundcloud": {
"message": "Soundcloud &#9660;"
},
"option_embedding_soundcloud_orig_link": {
"message": "Не убирать ссылку"
"message": "Soundcloud"
},
"option_embedding_pleercom": {
"message": "Pleer.com &#9660;"
},
"option_embedding_pleercom_nokita_server": {
"message": "Использовать сервер @NokitaKaze (deprecated)"
"message": "Pleer.com"
},
"option_embedding_coubcom": {
"message": "Coub.com &#9660;"
},
"option_embedding_coubcom_orig_link": {
"message": "Не убирать ссылку"
"message": "Coub.com"
},
"option_embedding_twitter_tweets": {
"message": "Twitter"
},
"option_embedding_instagram_posts": {
"message": "Instagram"
},
"option_embedding_remove_original_link": {
"message": "Удалять оригинальную ссылку"
},
"option_nsfw": {
"message": "Фильтрация NSFW-контента"
},
@ -113,8 +107,17 @@
"option_nsfw_blur_comments_entire": {
"message": "Размытие комментариев целиком"
},
"option_ctrl_enter": {
"message": "Отправлять текст по CTRL+Enter (устарело)"
"option_ajax": {
"message": "AJAX"
},
"option_ajax_comments": {
"message": "Отправка комментариев через AJAX (CTRL+Enter)"
},
"option_right_panel": {
"message": "Боковая панель справа"
},
"option_right_panel_to_unread": {
"message": "Кнопка \"Перейти к непрочитанному\""
},
"option_fluid_layout": {
"message": "&#34;Резиновая&#34; вёрстка (растянуть сайт по горизонтали)"
@ -135,16 +138,16 @@
"message": "Затухание подсветки через 20 секунд"
},
"option_ws_comments_notifications": {
"message": "Включить уведомления на рабочем столе"
"message": "Показывать всплывающие уведомления"
},
"option_ws_feeds": {
"message": "Обрабатывать ленты &#9660;"
"option_ws_posts": {
"message": "Обрабатывать посты &#9660;"
},
"option_ws_feeds_subscriptions": {
"message": "Подписки"
"option_ws_posts_add": {
"message": "Автоматически добавлять в ленту"
},
"option_ws_feeds_blogs": {
"message": "Блоги пользователей (только при подписке)"
"option_ws_posts_notifications": {
"message": "Показывать всплывающие уведомления"
},
"option_enlarge_font": {
"message": "Увеличить шрифт &#9660;"
@ -169,14 +172,34 @@
"message": "Заметки о пользователях на полях"
},
"option_other_comments_count_refresh":{
"message": "Обновляем количество непрочитанных комментариев и постов в ленте"
"message": "Обновление количества непрочитанных постов и комментариев в сайдбаре"
},
"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": "Сохранение черновика поста"
},
"options_feedback_text": {
"message": "<p>Нашли ошибку? Не стесняйтесь <a href=\"https:\/\/bitbucket.org\/skobkin\/chrome_point_plus\/issues?status=new&status=open\" target=\"_blank\">сообщить о ней<\/a>.<\/p><p>Также вы можете сделать пожертвование автору:<\/p><p><iframe frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" src=\"https:\/\/money.yandex.ru\/embed\/small.xml?account=41001539215836&quickpay=small&yamoney-payment-type=on&button-text=04&button-size=s&button-color=black&targets=Point%2B&default-sum=150&successURL=https%3A%2F%2Fbitbucket.org%2Fskobkin%2Fchrome_point_plus\" width=\"158\" height=\"31\"><\/iframe><\/p><p><iframe frameborder=\"0\" allowtransparency=\"true\" scrolling=\"no\" src=\"https:\/\/money.yandex.ru\/embed\/small.xml?account=41001539215836&quickpay=small&any-card-payment-type=on&button-text=04&button-size=s&button-color=black&targets=Point%2B&default-sum=150&successURL=https%3A%2F%2Fbitbucket.org%2Fskobkin%2Fchrome_point_plus\" width=\"158\" height=\"31\"><\/iframe><\/p><p><form action=\"https:\/\/www.paypal.com\/cgi-bin\/webscr\" method=\"post\" target=\"_top\"><input type=\"hidden\" name=\"cmd\" value=\"_s-xclick\"><input type=\"hidden\" name=\"hosted_button_id\" value=\"WW33X5J5WFSP4\"><input type=\"image\" src=\"https:\/\/www.paypalobjects.com\/ru_RU\/RU\/i\/btn\/btn_donateCC_LG.gif\" border=\"0\" name=\"submit\" alt=\"PayPal — более безопасный и легкий способ оплаты через Интернет!\"><img alt=\"\" border=\"0\" src=\"https:\/\/www.paypalobjects.com\/en_US\/i\/scr\/pixel.gif\" width=\"1\" height=\"1\"><\/form><\/p>"
},
"msg_comment_send_failed":{
"message": "Ошибка отправки комментария:"
},
"msg_saving_post_draft":{
"message": "Сохранение поста..."
},
"msg_success_recommendation": {
"message": "рекомендовано"
}
}

View File

@ -16,6 +16,11 @@
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) {
#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');

View File

@ -51,4 +51,4 @@
.markItUp .preview a {
background-image:url(chrome-extension://__MSG_@@extension_id__/images/markitup/sets/markdown/preview.png);
}
}

View File

@ -33,4 +33,4 @@
.wiki .markItUpEditor,
.dotclear .markItUpEditor {
background-image: url(chrome-extension://__MSG_@@extension_id__/images/markitup/skins/markitup/bg-editor-wiki.png);
}
}

View File

@ -1,8 +1,12 @@
/* @ before username */
#main #content a.user:before {
/* Posts */
#content .post-content a.user:before,
/* Subscribers */
#content .users span.user:before,
/* Subscriptions */
#content .users .info a.user:before {
content: "@";
}
/* Fix for recommendations in the feed */
#main #content .rec .user:before {
margin-right: -4px;
}
/* Fix for recommendations */
#content .post-content .rec .user:before {
margin-right: -3px;
}

View File

@ -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;
}

View File

@ -94,7 +94,7 @@ p
box-sizing: border-box;
max-height: 100%;
margin: 0;
padding: 10px 15px 5px;
padding: 20px 15px 5px;
border: none;
background: transparent;

View File

@ -28,31 +28,40 @@ div#markItUpText-input {
}
/* Auto-loaded Booru pictures */
.booru_pic {
.booru_pic, .instagram-post-embedded {
display: block !important;
float: none !important;
}
.booru_pic img {
.booru_pic img, .instagram-post-embedded img {
border: none;
max-width: 60%;
max-height: 300px;
}
/* Labels in post */
.post .post-id a .cn.changed_background {
/* Unique ID and Recomendation */
.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 {
padding: 0 .5em;
font-weight: normal;
color: #35587c;
background-color: #f2f2eb;
.pp-unique-comments
{
margin-right: .5em;
}
.post .post-id a .recommendation_count {
margin-left: 0.2em;
background-color: #f2eceb;
/* @todo i18n */
.pp-unique-comments::before
{
content: 'Комментаторов: ';
}
.pp-recommendation-count::before
{
content: 'Рекомендаций: ';
}
/* NSFW-content */
@ -115,7 +124,7 @@ div#markItUpText-input {
right: 5px;
top: 5px;
display: none;
background-image: url("//point.im/img/btn-edit.png");
background-image: url('//point.im/img/btn-edit.png');
background-size: 100% 100%;
width: 16px;
height: 16px;
@ -154,13 +163,97 @@ div#markItUpText-input {
}
/* Шваброточки */
#comments .post .nesting {
height: 24px;
float: left;
/** Индикация вложенности */
#comments.nesting_level {
overflow: hidden;
}
#comments .post:hover .nesting {
#comments.nesting_level .info::before {
position: absolute;
top: 0;
right: 100%;
display: block;
width: 500px;
height: 24px;
content: '';
opacity: 0;
background-image: url('chrome-extension://__MSG_@@extension_id__/images/nesting-point.svg');
background-repeat: repeat-x;
background-image: url('chrome-extension://__MSG_@@extension_id__/images/nesting-point.png');
background-position: right center;
}
#comments.nesting_level .post:hover .info::before {
transition: opacity .2s ease-in;
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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 B

View File

@ -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

View File

@ -1,205 +1,204 @@
// Maintaining options version
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'});
}
});
// Crutches and bikes
/**
* Inject several JS files
* @param {number} tabId Unique ID of tab which requested injection
* @param {Object[]} files Array of objects of files to inject
* @param {function} onAllInjected allback function running when injection ends
*/
function injectJS(tabId, files, onAllInjected) {
var item = files.shift();
if (item) {
console.log('Injecting JS "%s" to the tab #%s', item.file, tabId);
if ('file' in item) {
chrome.tabs.executeScript(tabId ? tabId : 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);
});
}
} else {
onAllInjected();
}
}
// @todo Implement injectCSS (because JS execution working always after CSS injection)
// Message listener
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
// @todo Check if sender.tab may be undefined in some cases
console.log('Received message from tab #%s: %O', sender.tab ? sender.tab.id : 'undefined', message);
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;
break;
case 'showNotification':
chrome.notifications.create(
message.notificationId, {
type: 'basic',
iconUrl: message.avatarUrl,
title: message.title,
message: message.text,
priority: 0,
isClickable: true
}, function(notificationId) {
console.info('Notification "%s" created', notificationId);
sendResponse(true);
}
);
// Fuck You, Chrome API documentation!!11
return true;
break;
case 'getManifestVersion':
sendResponse({version: getVersion()});
return true;
break;
case 'listenNotificationClicks':
// Adding notification click event listener
chrome.notifications.onClicked.addListener(function(notificationId) {
// Detecting notification type
if (notificationId.indexOf('comment_') === 0) {
tab_url = message.protocol + '//' + 'point.im/' + notificationId.replace(/comment_/g, '');
} else if (notificationId.indexOf('post_') === 0) {
tab_url = message.protocol + '//' + '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
});
}
});
sendResponse(true);
// Fuck You, Chrome API documentation!
return true;
break;
/**
* @deprecated since 1.19.1
*/
case 'injectJSFile':
console.log('Executing JS: %s', message.file);
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;
});
// Fuck You, Chrome API documentation!
return true;
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 {
/*
* May be not?
* But I don't want to block some shit-code execution
*/
sendResponse(false);
console.warn('No scripts executed (empty script array)');
}
// Fuck You, Chrome API documentation!
return true;
break;
/**
* @deprecated since 1.19.1
*/
case 'injectCSSFile':
console.log('Injecting CSS: "%s"', message.file);
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);
});
// 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() {
var VERSION = (function() {
/**
* @deprecated XMLHttpRequest in the background worker is deprecated
* according to the Chrome warning. But we definitely need synchronous
* AJAX here
*/
var xhr = new XMLHttpRequest();
xhr.open('GET', chrome.extension.getURL('manifest.json'), false);
xhr.send(null);
var manifest = JSON.parse(xhr.responseText);
return manifest.version;
}
var xhr = new XMLHttpRequest(),
manifest;
xhr.open('GET', chrome.extension.getURL('manifest.json'), false);
xhr.send(null);
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 {
onAllInjected(results);
}
}
/**
* @constructor Менеджер сообщений
*/
function MessageListener() {
/* jshint unused:false */
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (this.isMethodAvailable(message)) {
console.info('Call #%s() method for tab #%s', message.type, this.getTabId(sender));
this[message.type].apply(this, arguments);
return true;
} else {
console.warn('Method #%s() called from tab #%s does not exists', message.type, this.getTabId(sender));
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(
message.notificationId, {
type: 'basic',
iconUrl: message.avatarUrl,
title: message.title,
message: message.text,
priority: 0,
isClickable: true
}, function(notificationId) {
console.info('Notification "%s" created', notificationId);
sendResponse(true);
}
);
};
/**
* Получает версию плагина из манифеста
* @param {Object} message Сообщение
* @param {Object} sender Отправитель
* @param {Function} sendResponse Коллбек для обработки результата
*/
MessageListener.prototype.getManifestVersion = function(message, sender, sendResponse) {
sendResponse({ version: VERSION });
};
/**
* @param {Object} message Сообщение
*/
MessageListener.prototype.getFiles = function(message, defaultRunAt) {
var files;
if (! message.files) {
return false;
} else {
files = Array.isArray(message.files) ? message.files : [ message.files ];
return files.map(function(file) {
return {
file: typeof file === 'string' ? file : file.file,
runAt: file.runAt || defaultRunAt
};
});
}
};
/**
* Вставляет JS-файлы во вкладку
* @param {Object} message Сообщение
* @param {Object} sender Отправитель
* @param {Function} sendResponse Коллбек для обработки результата
*/
MessageListener.prototype.executeJSFiles = function(message, sender, sendResponse) {
var tabId = this.getTabId(sender);
injectFiles(
this.getFiles(message, 'document_end'),
function(file, callback) {
chrome.tabs.executeScript(tabId, file, callback);
},
sendResponse
);
};
/**
* Вставляет CSS-файлы во вкладку
* @param {Object} message Сообщение
* @param {Object} sender Отправитель
* @param {Function} sendResponse Коллбек для обработки результата
*/
MessageListener.prototype.injectCSSFiles = function(message, sender, sendResponse) {
var tabId = this.getTabId(sender);
injectFiles(
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
});
}
});

View File

@ -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];
}

View File

@ -1 +0,0 @@
(function(){var g={jQuery:"http://code.jquery.com/jquery-latest.min.js"};var j=function(){(function(k){k.fn.idTabs=function(){var n={};for(var m=0;m<arguments.length;++m){var l=arguments[m];switch(l.constructor){case Object:k.extend(n,l);break;case Boolean:n.change=l;break;case Number:n.start=l;break;case Function:n.click=l;break;case String:if(l.charAt(0)=="."){n.selected=l}else{if(l.charAt(0)=="!"){n.event=l}else{n.start=l}}break}}if(typeof n["return"]=="function"){n.change=n["return"]}return this.each(function(){k.idTabs(this,n)})};k.idTabs=function(n,m){var q=(k.metadata)?k(n).metadata():{};var o=k.extend({},k.idTabs.settings,q,m);if(o.selected.charAt(0)=="."){o.selected=o.selected.substr(1)}if(o.event.charAt(0)=="!"){o.event=o.event.substr(1)}if(o.start==null){o.start=-1}var l=function(){if(k(this).is("."+o.selected)){return o.change}var u="#"+this.href.split("#")[1];var s=[];var t=[];k("a",n).each(function(){if(this.href.match(/#/)){s.push(this);t.push("#"+this.href.split("#")[1])}});if(o.click&&!o.click.apply(this,[u,t,n,o])){return o.change}for(i in s){k(s[i]).removeClass(o.selected)}for(i in t){k(t[i]).hide()}k(this).addClass(o.selected);k(u).show();return o.change};var p=k("a[href*='#']",n).unbind(o.event,l).bind(o.event,l);p.each(function(){k("#"+this.href.split("#")[1]).hide()});var r=false;if((r=p.filter("."+o.selected)).length){}else{if(typeof o.start=="number"&&(r=p.eq(o.start)).length){}else{if(typeof o.start=="string"&&(r=p.filter("[href*='#"+o.start+"']")).length){}}}if(r){r.removeClass(o.selected);r.trigger(o.event)}return o};k.idTabs.settings={start:0,change:false,click:null,selected:".selected",event:"!click"};k.idTabs.version="2.2";k(function(){k(".idTabs").idTabs()})})(jQuery)};var a=function(l,k){k=k.split(".");while(l&&k.length){l=l[k.shift()]}return l};var c=document.getElementsByTagName("head")[0];var f=function(k){var l=document.createElement("script");l.type="text/javascript";l.src=k;c.appendChild(l)};var e=document.getElementsByTagName("script");var h=e[e.length-1].src;var b=true;for(d in g){if(a(this,d)){continue}b=false;f(g[d])}if(b){return j()}f(h)})();

View File

@ -49,4 +49,4 @@ miu = {
}
return '\n'+heading;
}
}
}

View File

@ -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);
};

View File

@ -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;
};

View File

@ -4,19 +4,19 @@
* При создании сохраняет версию, восстанавливает настройки, слушает изменения на инпутах.
* @constructor
*/
function Options() {
function OptionsPage() {
this.form = document.querySelector('form');
this.listenTabs();
chrome.runtime.sendMessage(null, {
type: 'getManifestVersion'
}, null, function(response) {
this.version = response.version || 'undefined';
this.showVersion();
this.restore();
this.form.addEventListener('change', this._onChange.bind(this));
}.bind(this));
}
@ -25,7 +25,7 @@ function Options() {
* Получает версию настроек. Если она не равна версии приложения, записывает в сторедж плагина настройки из инпутов
* и версию приложения.
*/
Options.prototype.updateOptionsFromFrom = function() {
OptionsPage.prototype.updateOptionsFromFrom = function() {
chrome.storage.sync.get('options_version', function(data) {
this.logVersion(data.options_version);
@ -40,7 +40,8 @@ Options.prototype.updateOptionsFromFrom = function() {
}, function() {
console.log('Default options initialized. Version upgraded to %s.', this.version);
if ( ! confirm(chrome.i18n.getMessage('options_text_new_version'))) {
/* global confirm */
if (! confirm(chrome.i18n.getMessage('options_text_new_version'))) {
window.close();
}
});
@ -51,7 +52,7 @@ Options.prototype.updateOptionsFromFrom = function() {
/**
* Сохраняет настройки
*/
Options.prototype.save = function() {
OptionsPage.prototype.save = function() {
var ppOptions = this.getValues();
console.log('Saving options: %O', ppOptions);
@ -62,7 +63,7 @@ Options.prototype.save = function() {
/**
* Получает настройки из стореджа плагина, устанавливает соответствующим инпутам соответствующие значения.
*/
Options.prototype.restore = function() {
OptionsPage.prototype.restore = function() {
this.checkOldStyle();
chrome.storage.sync.get('options', function(data) {
@ -80,6 +81,7 @@ Options.prototype.restore = function() {
break;
case 'enum':
case 'plain':
input.value = data.value;
break;
@ -97,19 +99,19 @@ Options.prototype.restore = function() {
/**
* @returns {Object} Хеш настроек вида { имяастроки: значениеастройки }
*/
Options.prototype.getValues = function() {
OptionsPage.prototype.getValues = function() {
return this._options;
};
/**
* @param {Event} event Событие изменения
*/
Options.prototype._onChange = function(event) {
OptionsPage.prototype._onChange = function(event) {
this.updateOptionFromInput(event.target);
this.save();
};
Options.prototype.updateOptionFromInput = function(input) {
OptionsPage.prototype.updateOptionFromInput = function(input) {
var key = this.getOptionKey(input.name);
if (this.isBoolean(input)) {
@ -122,6 +124,11 @@ Options.prototype.updateOptionFromInput = function(input) {
type: 'enum',
value: input.value
};
} else {
this._options[key] = {
type: 'plain',
value: input.value
};
}
};
@ -129,7 +136,7 @@ Options.prototype.updateOptionFromInput = function(input) {
* @param {HTMLElement} option Элемент опции
* @returns {Boolean} Является ли настройка булевой
*/
Options.prototype.isBoolean = function(option) {
OptionsPage.prototype.isBoolean = function(option) {
return option.getAttribute('type') === 'checkbox';
};
@ -138,7 +145,7 @@ Options.prototype.isBoolean = function(option) {
* @param {HTMLElement} option Элемент опции
* @returns {Boolean} Является ли настройка енумом
*/
Options.prototype.isEnum = function(option) {
OptionsPage.prototype.isEnum = function(option) {
return option.getAttribute('type') === 'radio';
};
@ -146,7 +153,7 @@ Options.prototype.isEnum = function(option) {
* @param {String} name Имя инпута
* @returns {String} Ключ для хеша настроек
*/
Options.prototype.getOptionKey = function(name) {
OptionsPage.prototype.getOptionKey = function(name) {
return name.replace(/-/g, '_');
};
@ -154,7 +161,7 @@ Options.prototype.getOptionKey = function(name) {
* @param {String} Ключ хеша настроек
* @returns {String} Имя инпута
*/
Options.prototype.getOptionName = function(key) {
OptionsPage.prototype.getOptionName = function(key) {
return key.replace(/_/g, '-');
};
@ -162,31 +169,34 @@ Options.prototype.getOptionName = function(key) {
* Выводит в консоль версию настроек и версию плагина
* @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);
};
/**
* Добавляет номер версии в подвал
*/
Options.prototype.showVersion = function() {
OptionsPage.prototype.showVersion = function() {
document.querySelector('#version').innerHTML = this.version;
};
/**
* Проверяет, не старого ли формата настройки. И если старого, то удаляет их.
*/
Options.prototype.checkOldStyle = function() {
OptionsPage.prototype.checkOldStyle = function() {
chrome.storage.sync.get('option_fancybox', function(data) {
if ((data.option_fancybox === true) || (data.option_fancybox === false)) {
console.log('Found old-style options. Cleaning...');
chrome.storage.sync.get(null, function(data) {
var option;
console.log('Old data: %O', data);
for (option in data) {
chrome.storage.sync.remove(option);
if (data.hasOwnProperty(option)) {
chrome.storage.sync.remove(option);
}
}
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.classList.remove('hidden');
@ -207,7 +217,7 @@ Options.prototype.updateStatus = function() {
/**
* Слушает события на табах
*/
Options.prototype.listenTabs = function() {
OptionsPage.prototype.listenTabs = function() {
var options = this;
options._selectedItem = document.querySelector('.tabs-item.selected');
@ -229,4 +239,4 @@ Options.prototype.listenTabs = function() {
});
};
new Options();
new OptionsPage();

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +1,68 @@
{
"manifest_version": 2,
"name": "Point+",
"version": "1.30.0",
"default_locale": "ru",
"author": "__MSG_ext_author__",
"homepage_url": "https://bitbucket.org/skobkin/chrome_point_plus",
"description": "__MSG_ext_description__",
"options_page": "options.html",
"page_action": {
"default_icon": {
"19": "images/icon19.png",
"38": "images/icon38.png"
},
"default_title": "__MSG_ext_page_action_title__",
"default_popup": "options.html"
},
"icons": {
"16": "images/icon16.png",
"32": "images/icon32.png",
"48": "images/icon48.png",
"64": "images/icon64.png",
"128": "images/icon128.png",
"256": "images/icon256.png"
},
"content_scripts": [
{
"matches": ["http://*.point.im/*", "https://*.point.im/*"],
"js": [
"vendor/jquery/jquery.min.js",
"js/bquery_ajax.js",
"js/point-plus.js"
],
"css": [
"css/point-plus.css"
],
"run_at": "document_end"
}
],
"web_accessible_resources": [
"images/*",
"includes/*",
"vendor/*",
"manifest.json"
],
"background": {
"scripts": ["js/background.js"]
},
"permissions": [
"http://*.point.im/*",
"https://*.point.im/*",
"https://pleer.com/*",
"http://player.soundcloud.com/*",
"https://player.soundcloud.com/*",
"https://api.kanaria.ru/point/*",
"https://*.twitter.com/*",
"storage",
"notifications",
"tabs"
]
}
{
"manifest_version": 2,
"name": "Point+",
"version": "1.42.1",
"default_locale": "ru",
"author": "__MSG_ext_author__",
"homepage_url": "https://bitbucket.org/skobkin/chrome_point_plus",
"description": "__MSG_ext_description__",
"options_page": "options.html",
"page_action": {
"default_icon": {
"19": "images/icon19.png",
"38": "images/icon38.png"
},
"default_title": "__MSG_ext_page_action_title__",
"default_popup": "options.html"
},
"icons": {
"16": "images/icon16.png",
"32": "images/icon32.png",
"48": "images/icon48.png",
"64": "images/icon64.png",
"128": "images/icon128.png",
"256": "images/icon256.png"
},
"content_scripts": [
{
"matches": ["http://*.point.im/*", "https://*.point.im/*"],
"js": [
"vendor/jquery/dist/jquery.min.js",
"js/options-manager.js",
"js/message-sender.js",
"js/point-plus.js"
],
"css": [
"css/point-plus.css"
],
"run_at": "document_end"
}
],
"web_accessible_resources": [
"images/*",
"includes/*",
"vendor/*",
"manifest.json"
],
"background": {
"scripts": ["js/background.js"]
},
"permissions": [
"http://point.im/*",
"https://point.im/*",
"http://*.point.im/*",
"https://*.point.im/*",
"https://pleer.com/*",
"http://player.soundcloud.com/*",
"https://player.soundcloud.com/*",
"https://api.kanaria.ru/point/*",
"https://*.twitter.com/*",
"https://api.instagram.com/*",
"https://coub.com/embed/*",
"storage",
"notifications",
"tabs"
]
}

View File

@ -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;
}

View File

@ -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');
});
};

View File

@ -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));
};

View File

@ -1,302 +1,307 @@
<!DOCTYPE html>
<html>
<head>
<title>Point Plus options</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/options.css" type="text/css">
</head>
<body>
<main>
<nav class="tabs-list">
<a class="tabs-item selected" href="#media" data-i18n="options_tabs_media"></a>
<a class="tabs-item" href="#other" data-i18n="options_tabs_other"></a>
<a class="tabs-item" href="#websocket" data-i18n="options_tabs_websocket"></a>
<a class="tabs-item" href="#feedback" data-i18n="options_tabs_feedback"></a>
</nav>
<form class="tabs-content">
<section class="tabs-content-item selected" id="media">
<div class="option-node">
<input type="checkbox" name="option-fancybox" id="option-fancybox">
<label for="option-fancybox" data-i18n="option_fancybox"></label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-images">
<span data-i18n="option_fancybox_images"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-videos">
<span data-i18n="option_fancybox_videos"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-posts">
<span data-i18n="option_fancybox_posts"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-bind-images-to-one-flow">
<span data-i18n="option_fancybox_bind_images_to_one_flow"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-smart-hints">
<span data-i18n="option_fancybox_smart_hints"></span>
</label>
</div>
<label class="option-node">
<input type="checkbox" name="option-images-load-original">
<span data-i18n="option_images_load_original"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-embedding" id="option-embedding">
<label for="option-embedding" data-i18n="option_embedding"></label>
<label class="option-node">
<input type="checkbox" name="option-images-load-booru">
<span data-i18n="option_images_load_booru"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-videos-parse-links" id="option-videos-parse-links">
<label for="option-videos-parse-links" data-i18n="option_videos_parse_links"></label>
<div class="option-node">
<label>
<input type="radio" name="option-videos-parse-links-type" value="webm">
<span data-i18n="option_videos_parse_webm"></span>
</label>
<label>
<input type="radio" name="option-videos-parse-links-type" value="all" checked="checked">
<span data-i18n="option_videos_parse_all_links"></span>
</label>
</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 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">
<input type="checkbox" name="option-audios-parse-leave-links">
<span data-i18n="option_embedding_soundcloud_orig_link"></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 class="option-node">
<input type="checkbox" name="option-embedding-pleercom-orig-link">
<span data-i18n="option_embedding_soundcloud_orig_link"></span>
</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">
<input type="checkbox" name="option-embedding-coubcom-orig-link">
<span data-i18n="option_embedding_coubcom_orig_link"></span>
</label>
</div>
<label class="option-node">
<input type="checkbox" name="option-embedding-twitter-tweets">
<span data-i18n="option_embedding_twitter_tweets"></span>
</label>
</div>
<div class="option-node">
<input type="checkbox" name="option-nsfw" id="option-nsfw">
<label for="option-nsfw" data-i18n="option_nsfw"></label>
<label class="option-node">
<input type="checkbox" name="option-nsfw-hide-posts">
<span data-i18n="option_nsfw_hide_posts"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-nsfw-blur-posts-images" id="option-nsfw-blur-posts-images">
<label for="option-nsfw-blur-posts-images" data-i18n="option_nsfw_blur_posts_images"></label>
<label class="option-node">
<input type="checkbox" name="option-nsfw-blur-posts-entire">
<span data-i18n="option_nsfw_blur_posts_entire"></span>
</label>
</div>
<div class="option-node">
<input type="checkbox" name="option-nsfw-blur-comments-images" id="option-nsfw-blur-comments-images">
<label for="option-nsfw-blur-comments-images" data-i18n="option_nsfw_blur_comments_images"></label>
<label class="option-node">
<input type="checkbox" name="option-nsfw-blur-comments-entire">
<span data-i18n="option_nsfw_blur_comments_entire"></span>
</label>
</div>
</div>
</section>
<section class="tabs-content-item" id="other">
<label class="option-node">
<input type="checkbox" name="option-ctrl-enter" disabled="disabled">
<span data-i18n="option_ctrl_enter"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fluid-layout">
<span data-i18n="option_fluid_layout"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-visual-editor-post">
<span data-i18n="option_visual_editor_post"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-search-with-google">
<span data-i18n="option_search_with_google"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-enlarge-font" id="option-enlarge-font">
<label for="option-enlarge-font" data-i18n="option_enlarge_font"></label>
<div class="option-node">
<label>
<input type="radio" name="option-enlarge-font-size" value="85" checked="checked"> 0.85 em
</label>
<label>
<input type="radio" name="option-enlarge-font-size" value="100"> 1 em
</label>
<label>
<input type="radio" name="option-enlarge-font-size" value="110"> 1.1 em
</label>
</div>
</div>
<label class="option-node">
<input type="checkbox" name="option-at-before-username">
<span data-i18n="option_at_before_username"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-hightlight-post-comments">
<span data-i18n="option_other_hightlight_post_comments"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-show-recommendation-count">
<span data-i18n="option_other_show_recommendation_count"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-scroll-space-key">
<span data-i18n="option_other_scroll_space_key"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-comments-nesting-level">
<span data-i18n="option_other_comments_nesting_level"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-other-comments-count-refresh" id="option-other-comments-count-refresh">
<label for="option-other-comments-count-refresh" data-i18n="option_other_comments_count_refresh"></label>
<label class="option-node">
<input type="checkbox" name="option-other-comments-count-refresh-title">
<span data-i18n="option_other_comments_count_refresh_title"></span>
</label>
</div>
<label class="option-node">
<input type="checkbox" name="option-other-comments-user-system">
<span data-i18n="option_other_comments_user_system"></span>
</label>
</section>
<section class="tabs-content-item" id="websocket">
<div class="option-node">
<input type="checkbox" name="option-ws" id="option-ws">
<label for="option-ws" data-i18n="option_ws"></label>
<div class="option-node">
<input type="checkbox" name="option-ws-comments" id="option-ws-comments">
<label for="option-ws-comments" data-i18n="option_ws_comments"></label>
<label class="option-node">
<input type="checkbox" name="option-ws-comments-color-fadeout">
<span data-i18n="option_ws_comments_color_fadeout"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-ws-comments-notifications">
<span data-i18n="option_ws_comments_notifications"></span>
</label>
</div>
<div class="option-node">
<input type="checkbox" name="option-ws-feeds" id="option-ws-feeds" disabled>
<label for="option-ws-feeds" data-i18n="option_ws_feeds"></label>
<label class="option-node">
<input type="checkbox" name="option-ws-feeds-subscriptions">
<span data-i18n="option_ws_feeds_subscriptions"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-ws-feeds-blogs">
<span data-i18n="option_ws_feeds_blogs"></span>
</label>
</div>
</div>
</section>
<section class="tabs-content-item" id="feedback">
<div data-i18n="options_feedback_text"></div>
</section>
</form>
</main>
<p class="saved hidden" data-i18n="options_text_saved"></p>
<footer class="footer">
<p>Point+ <span id="version"></span> by
<a href="https://skobkin-ru.point.im/" target="_blank">@skobkin-ru</a>,
<a href="https://isqua.point.im/" target="_blank">@isqua</a>,
<a href="https://nokitakaze.point.im/" target="_blank">@NokitaKaze</a>
</p>
</footer>
<script src="js/options.js"></script>
<script src="js/i18n.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title data-i18n="options_page_title"></title>
<link rel="stylesheet" href="css/options.css" type="text/css">
</head>
<body>
<main>
<nav class="tabs-list">
<a class="tabs-item selected" href="#media" data-i18n="options_tabs_media"></a>
<a class="tabs-item" href="#other" data-i18n="options_tabs_other"></a>
<a class="tabs-item" href="#websocket" data-i18n="options_tabs_websocket"></a>
<a class="tabs-item" href="#feedback" data-i18n="options_tabs_feedback"></a>
</nav>
<form class="tabs-content">
<section class="tabs-content-item selected" id="media">
<div class="option-node">
<input type="checkbox" name="option-fancybox" id="option-fancybox">
<label for="option-fancybox" data-i18n="option_fancybox"></label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-images">
<span data-i18n="option_fancybox_images"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-videos">
<span data-i18n="option_fancybox_videos"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-posts">
<span data-i18n="option_fancybox_posts"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-bind-images-to-one-flow">
<span data-i18n="option_fancybox_bind_images_to_one_flow"></span>
</label>
</div>
<label class="option-node">
<input type="checkbox" name="option-images-load-original">
<span data-i18n="option_images_load_original"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-embedding" id="option-embedding">
<label for="option-embedding" data-i18n="option_embedding"></label>
<label class="option-node">
<input type="checkbox" name="option-images-load-booru">
<span data-i18n="option_images_load_booru"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-videos-parse-links" id="option-videos-parse-links">
<label for="option-videos-parse-links" data-i18n="option_videos_parse_links"></label>
<div class="option-node">
<label>
<input type="radio" name="option-videos-parse-links-type" value="webm">
<span data-i18n="option_videos_parse_webm"></span>
</label>
<label>
<input type="radio" name="option-videos-parse-links-type" value="all" checked="checked">
<span data-i18n="option_videos_parse_all_links"></span>
</label>
</div>
</div>
<label class="option-node">
<input type="checkbox" name="option-audios-parse-links">
<span data-i18n="option_audios_parse_links"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-embedding-soundcloud">
<span data-i18n="option_embedding_soundcloud"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-embedding-pleercom">
<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 class="option-node">
<input type="checkbox" name="option-embedding-twitter-tweets">
<span data-i18n="option_embedding_twitter_tweets"></span>
</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 class="option-node">
<input type="checkbox" name="option-nsfw" id="option-nsfw">
<label for="option-nsfw" data-i18n="option_nsfw"></label>
<label class="option-node">
<input type="checkbox" name="option-nsfw-hide-posts">
<span data-i18n="option_nsfw_hide_posts"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-nsfw-blur-posts-images" id="option-nsfw-blur-posts-images">
<label for="option-nsfw-blur-posts-images" data-i18n="option_nsfw_blur_posts_images"></label>
<label class="option-node">
<input type="checkbox" name="option-nsfw-blur-posts-entire">
<span data-i18n="option_nsfw_blur_posts_entire"></span>
</label>
</div>
<div class="option-node">
<input type="checkbox" name="option-nsfw-blur-comments-images" id="option-nsfw-blur-comments-images">
<label for="option-nsfw-blur-comments-images" data-i18n="option_nsfw_blur_comments_images"></label>
<label class="option-node">
<input type="checkbox" name="option-nsfw-blur-comments-entire">
<span data-i18n="option_nsfw_blur_comments_entire"></span>
</label>
</div>
</div>
</section>
<section class="tabs-content-item" id="other">
<div class="option-node">
<input type="checkbox" name="option-ajax" id="option-ajax">
<label for="option-ajax" data-i18n="option_ajax"></label>
<label class="option-node">
<input type="checkbox" name="option-ajax-comments">
<span data-i18n="option_ajax_comments"></span>
</label>
</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">
<input type="checkbox" name="option-fluid-layout">
<span data-i18n="option_fluid_layout"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-visual-editor-post">
<span data-i18n="option_visual_editor_post"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-search-with-google">
<span data-i18n="option_search_with_google"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-enlarge-font" id="option-enlarge-font">
<label for="option-enlarge-font" data-i18n="option_enlarge_font"></label>
<div class="option-node">
<label>
<input type="radio" name="option-enlarge-font-size" value="85" checked="checked"> 0.85 em
</label>
<label>
<input type="radio" name="option-enlarge-font-size" value="100"> 1 em
</label>
<label>
<input type="radio" name="option-enlarge-font-size" value="110"> 1.1 em
</label>
</div>
</div>
<label class="option-node">
<input type="checkbox" name="option-at-before-username">
<span data-i18n="option_at_before_username"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-hightlight-post-comments">
<span data-i18n="option_other_hightlight_post_comments"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-show-recommendation-count">
<span data-i18n="option_other_show_recommendation_count"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-scroll-space-key">
<span data-i18n="option_other_scroll_space_key"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-other-comments-nesting-level">
<span data-i18n="option_other_comments_nesting_level"></span>
</label>
<div class="option-node">
<input type="checkbox" name="option-other-comments-count-refresh" id="option-other-comments-count-refresh">
<label for="option-other-comments-count-refresh" data-i18n="option_other_comments_count_refresh"></label>
<label class="option-node">
<input type="checkbox" name="option-other-comments-count-refresh-title">
<span data-i18n="option_other_comments_count_refresh_title"></span>
</label>
</div>
<label class="option-node">
<input type="checkbox" name="option-other-comments-user-system">
<span data-i18n="option_other_comments_user_system"></span>
</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 class="tabs-content-item" id="websocket">
<div class="option-node">
<input type="checkbox" name="option-ws" id="option-ws">
<label for="option-ws" data-i18n="option_ws"></label>
<div class="option-node">
<input type="checkbox" name="option-ws-comments" id="option-ws-comments">
<label for="option-ws-comments" data-i18n="option_ws_comments"></label>
<label class="option-node">
<input type="checkbox" name="option-ws-comments-color-fadeout">
<span data-i18n="option_ws_comments_color_fadeout"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-ws-comments-notifications">
<span data-i18n="option_ws_comments_notifications"></span>
</label>
</div>
<div class="option-node">
<input type="checkbox" name="option-ws-posts" id="option-ws-posts">
<label for="option-ws-posts" data-i18n="option_ws_posts"></label>
<label class="option-node">
<input type="checkbox" name="option-ws-posts-add" disabled>
<span data-i18n="option_ws_posts_add"></span>
</label>
<label class="option-node">
<input type="checkbox" name="option-ws-posts-notifications">
<span data-i18n="option_ws_posts_notifications"></span>
</label>
</div>
</div>
</section>
<section class="tabs-content-item" id="feedback">
<div data-i18n="options_feedback_text"></div>
</section>
</form>
</main>
<p class="saved hidden" data-i18n="options_text_saved"></p>
<footer class="footer">
<p>Point+ <span id="version"></span> by
<a href="https://skobkin-ru.point.im/" target="_blank">@skobkin-ru</a>,
<a href="https://isqua.point.im/" target="_blank">@isqua</a>,
<a href="https://nokitakaze.point.im/" target="_blank">@NokitaKaze</a>
</p>
</footer>
<script src="js/options.js"></script>
<script src="js/i18n.js"></script>
</body>
</html>

View File

@ -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

View File

@ -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>

8
pack_chromium.sh Normal file
View File

@ -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"

2
pack_zip.sh Normal file
View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
zip -9 -r chrome_point_plus.zip chrome_point_plus

View File

@ -1,10 +1,12 @@
{
"name": "chrome-point-plus",
"version": "1.30.0",
"version": "1.42.1",
"description": "Chrome extension for point.im",
"main": "index.js",
"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": {
"type": "git",
@ -15,7 +17,9 @@
"devDependencies": {
"bower": "^1.3.12",
"grunt": "^0.4.5",
"grunt-bump": "0.0.16",
"grunt-contrib-copy": "^0.7.0"
"grunt-bump": "^0.3.0",
"grunt-contrib-copy": "^0.7.0",
"jscs": "^1.10.0",
"jshint": "^2.6.0"
}
}