Compare commits

...

17 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
13 changed files with 347 additions and 327 deletions

View File

@ -1,5 +1,5 @@
var vendorCopy = [ var vendorCopy = [
'jquery/jquery.min.js', 'jquery/dist/jquery.min.js',
'fancybox/source/jquery.fancybox.pack.js', 'fancybox/source/jquery.fancybox.pack.js',
'fancybox/source/helpers/jquery.fancybox-media.js', 'fancybox/source/helpers/jquery.fancybox-media.js',

View File

@ -55,3 +55,9 @@ npm run lint
``` ```
grunt bump 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", "name": "chrome-point-plus",
"version": "1.40.1", "version": "1.42.1",
"authors": [ "authors": [
"Alexey Skobkin" "Alexey Skobkin"
], ],
@ -14,7 +14,7 @@
"chrome_point_plus/vendors/**" "chrome_point_plus/vendors/**"
], ],
"dependencies": { "dependencies": {
"jquery": "~1.10.1", "jquery": "~3",
"fancybox": "~2.1.5", "fancybox": "~2.1.5",
"markitup": "~1.1.14", "markitup": "~1.1.14",
"soundcloud": "git@github.com:soundcloud/Widget-JS-API.git" "soundcloud": "git@github.com:soundcloud/Widget-JS-API.git"

View File

@ -50,9 +50,6 @@
"option_fancybox_bind_images_to_one_flow": { "option_fancybox_bind_images_to_one_flow": {
"message": "Bind all images to one Fancybox gallery" "message": "Bind all images to one Fancybox gallery"
}, },
"option_fancybox_smart_hints": {
"message": "Generate image caption from tags"
},
"option_images_load_original": { "option_images_load_original": {
"message": "Load original images instead of thumbnails" "message": "Load original images instead of thumbnails"
}, },

View File

@ -50,9 +50,6 @@
"option_fancybox_bind_images_to_one_flow": { "option_fancybox_bind_images_to_one_flow": {
"message": "Связать все картинки в одну галерею Fancybox" "message": "Связать все картинки в одну галерею Fancybox"
}, },
"option_fancybox_smart_hints": {
"message": "Генерировать подписи к картинкам из тегов"
},
"option_images_load_original": { "option_images_load_original": {
"message": "Загружать оригиналы вместо миниатюр" "message": "Загружать оригиналы вместо миниатюр"
}, },

View File

@ -124,7 +124,7 @@ div#markItUpText-input {
right: 5px; right: 5px;
top: 5px; top: 5px;
display: none; display: none;
background-image: url("//point.im/img/btn-edit.png"); background-image: url('//point.im/img/btn-edit.png');
background-size: 100% 100%; background-size: 100% 100%;
width: 16px; width: 16px;
height: 16px; height: 16px;
@ -216,3 +216,44 @@ div#markItUpText-input {
background-position: 0 0; 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;
}

View File

@ -23,7 +23,10 @@ function PointPlus(ppVersion) {
console.info('Point+ %s', ppVersion); console.info('Point+ %s', ppVersion);
// Getting username // Getting username
var point_username = $('#name h1').text(); var point_username = $('#name').find('h1').text();
// Getting post id
var postId = $('#top-post').attr('data-id');
console.debug('Current post id detected as #%s', postId);
// Проверяем, загрузились ли мы // Проверяем, загрузились ли мы
var point_plus_debug = $('#point-plus-debug'); var point_plus_debug = $('#point-plus-debug');
@ -43,13 +46,15 @@ function PointPlus(ppVersion) {
// Options debug // Options debug
try { try {
console.debug('Options loaded: %O', options.getOptions()); console.debug('Options loaded: %O', options.getOptions());
} catch(e){} } catch(e) {
console.error('Options load error: %O', e);
}
create_tag_system(); create_tag_system();
// Move "all posts" to left menu // Move "all posts" to left menu
if (options.is('option_other_move_all_to_menu')) { if (options.is('option_other_move_all_to_menu')) {
$('div.secret a').insertAfter('a#menu-recent').css('background-image','url("img/icon-private-inactive.png")'); $('div.secret a').insertAfter('#left-menu #menu-recent').attr({'id': 'pp-left-menu-all'});
} }
// Side panel // Side panel
@ -64,11 +69,11 @@ function PointPlus(ppVersion) {
$('body').append($side_panel); $('body').append($side_panel);
if (options.is('option_right_panel_to_unread')) { if (options.is('option_right_panel_to_unread') && $('#comments').length > 0) {
$go_to_unread_block = $('<div>').attr({ $go_to_unread_block = $('<div>').attr({
id: 'pp-go-to-unread', id: 'pp-go-to-unread',
}).click(function() { }).click(function() {
var $unread_comment = $('#comments div.post.unread').first(); var $unread_comment = $('#comments').find('div.post.unread').first();
if ($unread_comment.length > 0) { if ($unread_comment.length > 0) {
$('html body').animate({ scrollTop: $unread_comment.offset().top }, 500); $('html body').animate({ scrollTop: $unread_comment.offset().top }, 500);
@ -115,9 +120,9 @@ function PointPlus(ppVersion) {
// Parse webm-links and create video instead // Parse webm-links and create video instead
if (options.is('option_videos_parse_links')) { if (options.is('option_videos_parse_links')) {
if (options.is('option_videos_parse_links_type', 'all')) { if (options.is('option_videos_parse_links_type', 'all')) {
parse_all_videos(options); parse_video_links(options, true);
} else { } else {
parse_webm(options); parse_video_links(options);
} }
} }
@ -221,13 +226,6 @@ function PointPlus(ppVersion) {
}); });
} }
// Правим хинты у фансибокса
if (options.is('option_fancybox_smart_hints')) {
fancybox_set_smart_hints();
} else {
$('div.post .postimg').attr('data-fancybox-title', ' ');
}
// Videos // Videos
if (options.is('option_fancybox_videos')) { if (options.is('option_fancybox_videos')) {
$('.postimg.youtube').addClass('fancybox-media').fancybox({ $('.postimg.youtube').addClass('fancybox-media').fancybox({
@ -257,10 +255,12 @@ function PointPlus(ppVersion) {
if (options.is('option_nsfw')) { if (options.is('option_nsfw')) {
$('.post-tag-nsfw,.post-tag-сиськи').find('a.postimg:not(.youtube)').attr('data-fancybox-group', 'hidden-images'); $('.post-tag-nsfw,.post-tag-сиськи').find('a.postimg:not(.youtube)').attr('data-fancybox-group', 'hidden-images');
$post = $('div.post');
if (options.is('option_nsfw_hide_posts')) { if (options.is('option_nsfw_hide_posts')) {
if ($('#comments').length == 0) { if ($('#comments').length == 0) {
console.log('Hide NSFW posts in feed, %i hidden', $('div.post').length); console.log('Hide NSFW posts in feed, %i hidden', $post.length);
$('div.post').addClass('hide-nsfw-posts'); $post.addClass('hide-nsfw-posts');
} }
} }
@ -274,7 +274,7 @@ function PointPlus(ppVersion) {
} }
// Blurred comments // Blurred comments
if ($('div.post').hasClass('post-tag-nsfw') || $('div.post').hasClass('post-tag-сиськи')) { if ($post.hasClass('post-tag-nsfw') || $post.hasClass('post-tag-сиськи')) {
if (options.is('option_nsfw_blur_comments_entire')) { if (options.is('option_nsfw_blur_comments_entire')) {
console.log('Bluring comments'); console.log('Bluring comments');
$('#comments').addClass('blur-nsfw-entire'); $('#comments').addClass('blur-nsfw-entire');
@ -374,7 +374,7 @@ function PointPlus(ppVersion) {
} }
// Google search // Google search
if (options.is('option_search_with_google')) { if (options.is('option_search_with_google')) {
$('#search-form input[type="text"]').attr('placeholder', 'Google').keydown(function(e) { $('#search-form').find('input[type="text"]').attr('placeholder', 'Google').keydown(function(e) {
if (e.keyCode == 10 || e.keyCode == 13) { if (e.keyCode == 10 || e.keyCode == 13) {
e.preventDefault(); e.preventDefault();
document.location.href = '//www.google.ru/search?q=site%3Apoint.im+' + $(this).val(); document.location.href = '//www.google.ru/search?q=site%3Apoint.im+' + $(this).val();
@ -387,11 +387,8 @@ function PointPlus(ppVersion) {
ws = new WebSocket(((location.protocol == 'https:') ? 'wss' : 'ws') + '://point.im/ws'); ws = new WebSocket(((location.protocol == 'https:') ? 'wss' : 'ws') + '://point.im/ws');
console.log('WebSocket created: %O', ws); console.log('WebSocket created: %O', ws);
// Detecting post id if presented
var postId = $('#top-post').attr('data-id');
console.debug('Current post id detected as #%s', postId);
// Detecting view mode // Detecting view mode
treeSwitch = $('#tree-switch a.active').attr('href'); treeSwitch = $('#tree-switch').children('a.active').attr('href');
console.debug('Comments view mode: %s', treeSwitch); console.debug('Comments view mode: %s', treeSwitch);
// Error handler // Error handler
@ -399,6 +396,12 @@ function PointPlus(ppVersion) {
console.error('WebSocket error: %O', err); console.error('WebSocket error: %O', err);
}; };
// Close handler
ws.onclose = function(evt) {
console.error('WebSocket closed: %O', evt);
};
// todo: refactor to background service
// Message handler // Message handler
ws.onmessage = function(evt) { ws.onmessage = function(evt) {
try { try {
@ -427,17 +430,13 @@ function PointPlus(ppVersion) {
// Recommendation comment // Recommendation comment
case 'ok': case 'ok':
// Do not break here. Using next case for this message // Do not break here. Using next case for this message
// Comments // Comments
case 'comment': case 'comment':
if (wsMessage.a === 'comment') { console.groupCollapsed('WS \'%s\' #%s/%s', wsMessage.a, wsMessage.post_id, wsMessage.comment_id);
console.groupCollapsed('WS comment #%s/%s', wsMessage.post_id, wsMessage.comment_id);
} else if (wsMessage.a === 'ok') {
console.groupCollapsed('WS comment rec #%s/%s', wsMessage.post_id, wsMessage.comment_id);
}
// Check option // Check option
if ( ! options.is('option_ws_comments')) { if (!options.is('option_ws_comments')) {
console.log('Comments processing disabled'); console.log('Comments processing disabled');
console.groupEnd(); console.groupEnd();
break; break;
@ -457,56 +456,61 @@ function PointPlus(ppVersion) {
break; break;
} }
// Generating comment from websocket message // If comment has text
create_comment_elements({ if (wsMessage.hasOwnProperty('html') && typeof wsMessage.html === 'string') {
id: (wsMessage.a === 'ok') ? wsMessage.rcid : wsMessage.comment_id, // Generating comment from websocket message
toId: wsMessage.to_comment_id, create_comment_elements({
postId: wsMessage.post_id, id: (wsMessage.a === 'ok') ? wsMessage.rcid : wsMessage.comment_id,
author: wsMessage.author, toId: wsMessage.to_comment_id,
html: wsMessage.html, postId: wsMessage.post_id,
fadeOut: options.is('option_ws_comments_color_fadeout'), author: wsMessage.author,
isRec: (wsMessage.a === 'ok') ? true : false, html: wsMessage.html,
unread: (point_username && point_username !== wsMessage.author) ? true : false, fadeOut: options.is('option_ws_comments_color_fadeout'),
}, function($comment) { isRec: (wsMessage.a === 'ok'),
// It's time to DOM unread: (point_username && point_username !== wsMessage.author) ? true : false,
console.info('Inserting comment'); }, function($comment) {
// It's time to DOM
// Search for parent comment console.info('Inserting comment');
$parentComment = (wsMessage.to_comment_id) ? ($('div.post[data-comment-id="' + wsMessage.to_comment_id + '"]')) : [];
console.log('Parent comment: %O', $parentComment || null); // Search for parent comment
$parentComment = (wsMessage.to_comment_id) ? ($('div.post[data-comment-id="' + wsMessage.to_comment_id + '"]')) : [];
// If list mode or not addressed to other comment console.log('Parent comment: %O', $parentComment || null);
if ($('#comments #tree-switch a').eq(0).hasClass('active') || (wsMessage.to_comment_id === null) || (!$parentComment.length)) {
// Adding to the end of the list // If list mode or not addressed to other comment
$('.content-wrap #comments #post-reply').before($comment); if (treeSwitch === '?tree=0' || !wsMessage.to_comment_id || !$parentComment.length) {
} else { // Adding to the end of the list
// Check for children $('.content-wrap #comments #post-reply').before($comment);
$parentCommentChildren = $parentComment.next('.comments');
// If child comment already exist
if ($parentCommentChildren.length > 0) {
console.log('Child comments found. Appending...');
$parentCommentChildren.append($comment);
} else { } else {
console.log('No child comments found. Creating...'); // Check for children
$parentComment.after($('<div>').addClass('comments').append($comment)); $parentCommentChildren = $parentComment.next('.comments');
// If child comment already exist
if ($parentCommentChildren.length > 0) {
console.log('Child comments found. Appending...');
$parentCommentChildren.append($comment);
} else {
console.log('No child comments found. Creating...');
$parentComment.after($('<div>').addClass('comments').append($comment));
}
} }
}
// Desktop notifications // Desktop notifications
if (options.is('option_ws_comments_notifications')) { if (options.is('option_ws_comments_notifications')) {
console.log('Showing desktop notification'); console.log('Showing desktop notification');
messenger.sendMessage({ messenger.sendMessage({
type: 'showNotification', type: 'showNotification',
notificationId: 'comment_' + wsMessage.post_id + '#' + wsMessage.comment_id, notificationId: 'comment_' + wsMessage.post_id + '#' + wsMessage.comment_id,
avatarUrl: getProtocol() + '//point.im/avatar/' + wsMessage.author + '/80', avatarUrl: getProtocol() + '//point.im/avatar/' + wsMessage.author + '/80',
title: '@' + wsMessage.author + ' #' + wsMessage.post_id + '/' + wsMessage.comment_id, title: '@' + wsMessage.author + ' #' + wsMessage.post_id + '/' + wsMessage.comment_id,
text: wsMessage.text text: wsMessage.text
}, function(response) {}); }, function(response) {});
} }
console.groupEnd(); // Updating comments number
}); update_right_panel_unread_count();
console.groupEnd();
});
}
break; break;
@ -553,7 +557,6 @@ function PointPlus(ppVersion) {
console.log(e); console.log(e);
console.log(evt.data); console.log(evt.data);
} }
;
}; };
} }
// Font size // Font size
@ -700,7 +703,7 @@ function create_comment_elements(commentData, onCommentCreated) {
$commentTemplate.find('.action-labels .more-label').attr('for', 'action-' + commentData.postId + '_' + commentData.id); $commentTemplate.find('.action-labels .more-label').attr('for', 'action-' + commentData.postId + '_' + commentData.id);
$commentTemplate.find('.post-content input[name="action-radio"]').attr('id', 'action-' + commentData.postId + '_' + commentData.id); $commentTemplate.find('.post-content input[name="action-radio"]').attr('id', 'action-' + commentData.postId + '_' + commentData.id);
// Bookmark link // Bookmark link
$commentTemplate.find('.action-buttons a.bookmark').attr('href', $('#top-post .info a').attr('href') + commentData.postId + '/b?comment_id=' + commentData.id + '&csrf_token=' + csRfToken); $commentTemplate.find('.action-buttons a.bookmark').attr('href', $('#top-post').find('.info a').attr('href') + commentData.postId + '/b?comment_id=' + commentData.id + '&csrf_token=' + csRfToken);
// Reply form // Reply form
$commentTemplate.find('.post-content input.reply-radio').attr('id', 'reply-' + commentData.postId + '_' + commentData.id); $commentTemplate.find('.post-content input.reply-radio').attr('id', 'reply-' + commentData.postId + '_' + commentData.id);
$commentTemplate.find('.post-content form.reply-form').attr('action', '/' + commentData.postId); $commentTemplate.find('.post-content form.reply-form').attr('action', '/' + commentData.postId);
@ -731,7 +734,7 @@ function create_comment_elements(commentData, onCommentCreated) {
* @param {?object} $span jQuery object of unread count <span> * @param {?object} $span jQuery object of unread count <span>
*/ */
function update_right_panel_unread_count($span) { function update_right_panel_unread_count($span) {
var unread_count = $('#comments div.post.unread').length; var unread_count = $('#comments').find('div.post.unread').length;
if (typeof $span === 'undefined') { if (typeof $span === 'undefined') {
$span = $('#pp-unread-count'); $span = $('#pp-unread-count');
@ -743,123 +746,139 @@ function update_right_panel_unread_count($span) {
} }
// Помечаем непрочитанные посты более видимо чем каким-то баджем // Помечаем непрочитанные посты более видимо чем каким-то баджем
// Эта часть написана @RainbowSpike // Эта часть изначально была написана @RainbowSpike
function mark_unread_post() { function mark_unread_post() {
var divs = $(".content-wrap > div.post").css({'padding-left':'2px'}); // массив постов var $posts = $('.content-wrap').children('div.post');
for (var i = 0; i < divs.length; i++) { // обыск постов $posts.css({'padding-left':'2px'});
var spans = $(divs[i]).find(".unread"); // поиск метки непрочитанных комментов
if (spans.length > 0) { // если в посте есть непрочитанные комменты... $posts.each(function() {
$(divs[i]).css({//...залить пост зеленоватым и скруглить if ($(this).find('.post-id .unread').length > 0) {
'background-color': '#EEFFEE', $(this).addClass('pp-post-unread');
'border-radius': '10px'
});
} }
});
}
/**
* Parse video links in posts
*
* @param {object} current_options
* @param {boolean} all
*/
function parse_video_links(current_options, all) {
if (typeof all === 'undefined') {
all = false;
} }
} var regex;
if (all) {
regex = new RegExp('\\.(webm|avi|mp4|mpg|mpeg)(\\?.+)?$', 'i');
} else {
regex = new RegExp('\\.(webm)(\\?.+)?$', 'i');
}
// Webm
function parse_webm(current_options) {
$('.post-content a:not(.booru_pic)').each(function(num, obj) { $('.post-content a:not(.booru_pic)').each(function(num, obj) {
var href = obj.href; var href = obj.href;
var n = null; var matches;
if (n = href.match(new RegExp('\\.webm(\\?.+)?$', 'i'))) { if (matches = href.match(regex)) {
var player = document.createElement('video'); var player = document.createElement('video');
var mime = video_extension_to_mime(matches[1]);
// Там может быть не vp8+vorbis, но мы этого никак не узнаем // Там может быть не vp8+vorbis, но мы этого никак не узнаем
$(player).html('<source src="' + href + '" type=\'video/webm; codecs="vp8, vorbis"\' />').attr('controls', 'controls').css({ $(player)
'display': 'block', .html('<source src="' + href + '" type=\'' + mime + '\' />')
'max-width': '95%' .attr('controls', 'controls')
}).addClass('parsed-webm-link'); .addClass('pp-video-player')
;
obj.parentElement.insertBefore(player, obj); obj.parentElement.insertBefore(player, obj);
if (current_options.is('option_embedding_remove_original_link')) { if (current_options.is('option_embedding_remove_original_link')) {
$(obj).hide(); $(obj).remove();
}
}
});
}
// Видео
function parse_all_videos(current_options) {
$('.post-content a:not(.booru_pic)').each(function(num, obj) {
var href = obj.href;
var n = null;
if (n = href.match(new RegExp('\\.(webm|avi|mp4|mpg|mpeg)(\\?.+)?$', 'i'))) {
var player = document.createElement('video');
var mime = video_extension_to_mime(n[1]);
$(player).html('<source src="' + href + '" type=\'' + mime + '\' />').attr('controls', 'controls').css({
'display': 'block',
'max-width': '95%'
}).addClass('parsed-webm-link');
obj.parentElement.insertBefore(player, obj);
if (current_options.is('option_embedding_remove_original_link')) {
$(obj).hide();
} }
} }
}); });
} }
/**
* Detects mime and codecs by file extension
*
* @param {string} extension
* @returns {string}
*/
function video_extension_to_mime(extension) { function video_extension_to_mime(extension) {
switch (extension) { switch (extension) {
case 'webm':return 'video/webm; codecs="vp8, vorbis'; case 'webm':
case 'avi' :return 'video/avi;'; return 'video/webm; codecs="vp8, vorbis"';
case 'mp4' :return 'video/mp4;'; case 'avi':
case 'mpg' :return 'video/mp4;'; return 'video/avi;';
case 'mpeg':return 'video/mp4;'; case 'mp4':
return 'video/mp4;';
case 'mpg':
return 'video/mp4;';
case 'mpeg':
return 'video/mp4;';
} }
} }
// Аудио // Аудио
function parse_all_audios(current_options){ function parse_all_audios(current_options) {
var regex_all = new RegExp('^https?:\\/\\/([a-z0-9.-]+)\\/[a-z0-9_\\/.%-]+\\.(mp3|ogg|wav)(\\?.+)?$', 'i');
var regex_vk = new RegExp('\\.vk\\.me$', 'i');
$('.post-content a').each(function(num, obj) { $('.post-content a').each(function(num, obj) {
if ($(obj).hasClass('booru_pic')) { if ($(obj).hasClass('booru_pic')) {
return; return;
} }
var href = obj.href; var href = obj.href;
var n = null; var n;
if (n = href.match(new RegExp('^https?:\\/\\/([a-z0-9.-]+)\\/[a-z0-9_\\/.%-]+\\.(mp3|ogg|wav)(\\?.+)?$', 'i'))) { if (n = href.match(regex_all)) {
var domain = n[1]; var domain = n[1];
// Проверяем откуда мы грузимся // Проверяем откуда мы грузимся
if (domain.match(new RegExp('\\.vk\\.me$', 'i'))){ if (domain.match(regex_vk)) {
// Так то ж Контакт! // Так то ж Контакт!
if (typeof(n[3])=='undefined'){ if (typeof(n[3])=='undefined') {
return; return;
} }
if (!n[3].match('extra\\=', 'i')){ if (!n[3].match('extra\\=', 'i')) {
return; return;
} }
} }
var player = document.createElement('audio'); var player = document.createElement('audio');
var mime = audio_extension_to_mime(n[2]); var mime = audio_extension_to_mime(n[2]);
$(player).html('<source src="' + href + '" type=\'' + mime + '\' />').attr('controls', 'controls').css({
'display': 'block', $(player)
'max-width': '350px' .html('<source src="' + href + '" type=\'' + mime + '\' />')
}).addClass('parsed-audio-link'); .attr('controls', 'controls')
.addClass('pp-audio-player')
;
obj.parentElement.insertBefore(player, obj); obj.parentElement.insertBefore(player, obj);
if (current_options.is('option_embedding_remove_original_link')) { if (current_options.is('option_embedding_remove_original_link')) {
$(obj).hide(); $(obj).remove();
} }
} }
}); });
} }
/**
* Detects mime and codecs by audio file extension
*
* @param extension
* @returns {*}
*/
function audio_extension_to_mime(extension) { function audio_extension_to_mime(extension) {
switch (extension) { switch (extension) {
case 'mp3': return 'audio/mpeg'; case 'mp3':
case 'ogg': return 'audio/ogg; codecs=vorbis'; return 'audio/mpeg';
case 'wav': return 'audio/vnd.wave'; case 'ogg':
return 'audio/ogg; codecs="vorbis"';
case 'wav':
return 'audio/vnd.wave';
} }
} }
@ -867,19 +886,21 @@ function audio_extension_to_mime(extension) {
* Показывает количество рекомендаций и комментаторов у постов * Показывает количество рекомендаций и комментаторов у постов
*/ */
function set_posts_count_label() { function set_posts_count_label() {
var posts = {}; $posts = $('.content-wrap').children('div.post');
var posts_hash = {};
var ids; var ids;
$('.content-wrap > div.post').each(function(n, post) { $posts.each(function(n, post) {
var $post = $(post); var $post = $(post);
var postId = $post.data('id'); var postId = $post.data('id');
posts[postId] = $post; posts_hash[postId] = $post;
}); });
ids = Object.keys(posts); ids = Object.keys(posts_hash);
$('.content-wrap > div.post .post-id a .cn').addClass('changed_background'); $posts.find('.post-id .cn').addClass('changed_background');
$.ajax('https://api.kanaria.ru/point/get_post_info.php?list=' + encodeURIComponent(ids.join(',')), { $.ajax('https://api.kanaria.ru/point/get_post_info.php?list=' + encodeURIComponent(ids.join(',')), {
dataType: 'json', dataType: 'json',
@ -888,15 +909,15 @@ function set_posts_count_label() {
var postInfo = data.list[id]; var postInfo = data.list[id];
if (postInfo) { if (postInfo) {
posts[id].find('.post-id').after( posts_hash[id].find('.post-id').after(
'<div class="pp-post-counters">' + '<div class="pp-post-counters">' +
'<span class="pp-unique-comments"></span> ' + '<span class="pp-unique-comments"></span> ' +
'<span class="pp-recommendation-count"></span> ' + '<span class="pp-recommendation-count"></span> ' +
'</div>' '</div>'
) );
posts[id].find('.pp-unique-comments').text(postInfo.count_comment_unique); posts_hash[id].find('.pp-unique-comments').text(postInfo.count_comment_unique);
posts[id].find('.pp-recommendation-count').text(postInfo.count_recommendation); posts_hash[id].find('.pp-recommendation-count').text(postInfo.count_recommendation);
} }
}); });
} }
@ -904,10 +925,12 @@ function set_posts_count_label() {
} }
function parse_pleercom_links(current_options) { function parse_pleercom_links(current_options) {
var regex = new RegExp('^https?:\\/\\/pleer\\.com\\/tracks\\/([0-9a-z]+)', 'i');
$('.post-content a').each(function(num, link) { $('.post-content a').each(function(num, link) {
var $link = $(link); var $link = $(link);
var href = link.href; var href = link.href;
var matches = href.match(new RegExp('^https?:\\/\\/pleer\\.com\\/tracks\\/([0-9a-z]+)', 'i')); var matches = href.match(regex);
if (matches) { if (matches) {
trackHref = 'http://embed.pleer.com/normal/track?id=' + matches[1] + '&t=grey'; trackHref = 'http://embed.pleer.com/normal/track?id=' + matches[1] + '&t=grey';
@ -924,9 +947,11 @@ function parse_pleercom_links(current_options) {
} }
// Проставляем теги у постов // Проставляем теги у постов
// @todo Переписать блокировку тегов и убрать подобное выставление тегов в виде классов
// @hint В данный момент эта фича используются для NSFW, потом выборку по тегам можно будет использовать много где // @hint В данный момент эта фича используются для NSFW, потом выборку по тегам можно будет использовать много где
function create_tag_system() { function create_tag_system() {
$('.content-wrap > div.post').each(function() { $('.content-wrap').children('div.post').each(function() {
// @todo refactor
var tags = $(this).find('div.tags a.tag'); var tags = $(this).find('div.tags a.tag');
for (var i = 0; i < tags.length; i++) { for (var i = 0; i < tags.length; i++) {
var tag_name = $(tags[i]).html().toLowerCase(); var tag_name = $(tags[i]).html().toLowerCase();
@ -949,8 +974,7 @@ function set_space_key_skip_handler() {
return; return;
} }
var k = event.keyCode; if (32 == event.keyCode) {
if (k == 32) {
space_key_event(); space_key_event();
return false; return false;
} }
@ -1006,13 +1030,17 @@ var draft_waiting = false;
* Restore draft from localStorage * Restore draft from localStorage
*/ */
function draft_restore() { function draft_restore() {
var $post_form = $('#new-post-form');
var $text_input = $post_form.find('#text-input');
var $tags_input = $post_form.find('#tags-input');
chrome.storage.local.get(['point_draft_text', 'point_draft_tags'], function(items) { chrome.storage.local.get(['point_draft_text', 'point_draft_tags'], function(items) {
if ($('#new-post-form #text-input').val() === '') { if ($text_input.val() === '') {
$('#new-post-form #text-input').val(items.point_draft_text); $text_input.val(items.point_draft_text);
draft_last_text = items.point_draft_text; draft_last_text = items.point_draft_text;
} }
if ($('#new-post-form #tags-input').val() === '') { if ($tags_input.val() === '') {
$('#new-post-form #tags-input').val(items.point_draft_tags); $tags_input.val(items.point_draft_tags);
draft_last_tags = items.point_draft_tags; draft_last_tags = items.point_draft_tags;
} }
}); });
@ -1031,7 +1059,7 @@ function draft_set_save_handler() {
} }
}); });
// Adding span indicator // Adding span indicator
$('#new-post-wrap .footnote').append($('<span id="draft-save-status">')); $('#new-post-wrap').find('.footnote').append($('<span id="draft-save-status">'));
} }
/** /**
@ -1048,8 +1076,10 @@ function draft_save_check() {
} }
} }
var current_text = $('#new-post-form #text-input').val(); var $post_form = $('#new-post-form');
var current_tags = $('#new-post-form #tags-input').val();
var current_text = $post_form.find('#text-input').val();
var current_tags = $post_form.find('#tags-input').val();
if ((draft_last_text === current_text) && (draft_last_tags === current_tags)) { if ((draft_last_text === current_text) && (draft_last_tags === current_tags)) {
draft_save_busy = false; draft_save_busy = false;
@ -1058,7 +1088,7 @@ function draft_save_check() {
draft_save_busy = true; draft_save_busy = true;
draft_save_last_time = new Date(); draft_save_last_time = new Date();
// @todo i18n // @todo i18n
$('#draft-save-status').text(chrome.i18n.getMessage('msg_saving_post_draft')).show(); $('#draft-save-status').text(chrome.i18n.getMessage('msg_saving_post_draft')).show();
@ -1084,95 +1114,38 @@ function draft_save_check() {
// Парсим ссылки на coub // Парсим ссылки на coub
function parse_coub_links(current_options) { function parse_coub_links(current_options) {
var regex = new RegExp('^https?:\\/\\/coub\\.com\\/view\\/([0-9a-z]+)', 'i');
$('.post-content a').each(function(num, obj) { $('.post-content a').each(function(num, obj) {
var href = obj.href; var href = obj.href;
var n = null; var matches;
if (n = href.match(new RegExp('^https?:\\/\\/coub\\.com\\/view\\/([0-9a-z]+)', 'i'))) { if (matches = href.match(regex)) {
var player = document.createElement('iframe'); var player = document.createElement('iframe');
var parent_width = $(obj.parentElement).width(); var parent_width = $(obj.parentElement).width();
$(player).attr({ $(player)
'src': 'https://coub.com/embed/' + n[1] + '?muted=false&autostart=false&originalSize=false&hideTopBar=false&startWithHD=true', .attr({
'allowfullscreen': 'true' 'src': 'https://coub.com/embed/' + matches[1] + '?muted=false&autostart=false&originalSize=false&hideTopBar=false&startWithHD=true',
}).css({ 'allowfullscreen': 'true'
'max-width': '640px', })
'border': 'none', .css({
'width': Math.floor(parent_width * 0.9), 'width': Math.floor(parent_width * 0.9),
'height': Math.ceil(parent_width * 0.9 * 480 / 640) 'height': Math.ceil(parent_width * 0.9 * 480 / 640)
}).addClass('embeded_video').addClass('embeded_video_' + n[1]); })
.addClass('pp-video-player-coub')
.addClass('embeded_video')
.addClass('embeded_video_' + matches[1])
;
obj.parentElement.insertBefore(player, obj); obj.parentElement.insertBefore(player, obj);
if (current_options.is('option_embedding_remove_original_link')) { if (current_options.is('option_embedding_remove_original_link')) {
$(obj).hide(); $(obj).remove();
} }
} }
}); });
} }
// Правим хинт в FancyBox
function fancybox_set_smart_hints(){
$('div.post').each(function() {
var all_post_images = $(this).find('.postimg');
if (all_post_images.length == 0) {
return;
}
var tags = $(this).find('div.tags a.tag');
var default_hint_text = '';// Дефолтный текст для хинта в FancyBox, если не нашлость другого
// Сначала теги
for (var i = 0; i < tags.length; i++) {
var tag_name = $(tags[i]).html().toLowerCase();
default_hint_text += ' ' + tag_name;
}
// Потом текст
var textcontent = $(this).find('.text-content');
if (textcontent.length > 0) {
textcontent = textcontent[0];
for (var i = 0; i < textcontent.childNodes.length; i++) {
var current_child_node = textcontent.childNodes[i];
if ((current_child_node.nodeName !== 'P') && (current_child_node.nodeName !== '#text')) {
continue;
}
var a = $(current_child_node).find('a.postimg');
if (a.length > 0) {
continue;
}
var tmp_str = current_child_node.textContent.replace(/(\n(\r)?)/g, ' ');
tmp_str = tmp_str.replace("\t", " ");
default_hint_text += ' ' + tmp_str;
}
}
// Режем текст
default_hint_text = default_hint_text.replace(new RegExp(' {2,}'), ' ').replace(new RegExp(' +$'), '').substr(1);
if (default_hint_text.length > 140) {
default_hint_text = default_hint_text.substr(0, 140 - 3) + '...';
}
// Выставляем дефолтный
all_post_images.attr('data-fancybox-title', default_hint_text);
// А теперь перебираем по одному все картинки
var paragraphs = $(this).find('.post-content > .text > p, .post-content > .text, .text-content > p, .text-content');
paragraphs.each(function() {
var nodes = this.childNodes;
for (var i = 0; i < nodes.length - 2; i++) {
if ($(nodes[i]).hasClass('booru_pic')) {
if (nodes[i + 2].nodeName == '#text') {
$(nodes[i]).attr('data-fancybox-title', nodes[i + 2].textContent);
i += 2;
continue;
}
}
}
});
});
}
/** /**
* Система заметок о пользователях * Система заметок о пользователях
* https://bitbucket.org/skobkin/chrome_point_plus/issue/50/--------------------------- * https://bitbucket.org/skobkin/chrome_point_plus/issue/50/---------------------------
@ -1202,8 +1175,8 @@ function hints_draw_main_user_hint(items) {
} }
var current_user_hint_block = document.createElement('div'); var current_user_hint_block = document.createElement('div');
$('.aside .aside-content #counters')[0].parentElement. var $counters = $('.aside-content #counters');
insertBefore(current_user_hint_block, $('.aside .aside-content #counters')[0]); $counters[0].parentElement.insertBefore(current_user_hint_block, $counters[0]);
$(current_user_hint_block).addClass('current-user-hint'); $(current_user_hint_block).addClass('current-user-hint');
// Рисуем кнопки управления // Рисуем кнопки управления
@ -1263,17 +1236,19 @@ function safe_saned_text(text, object) {
// Рисуем title'ы на всех доступных пользователях, точнее на их аватарках // Рисуем title'ы на всех доступных пользователях, точнее на их аватарках
function hints_set_titles_on_users(items) { function hints_set_titles_on_users(items) {
var regex = new RegExp('^https?\\://([0-9a-z-]+)\\.point\\.im/$', 'i');
$('a').each(function() { $('a').each(function() {
var href = $(this).attr('href'); var href = $(this).attr('href');
if (typeof(href) == 'undefined') { if (typeof(href) == 'undefined') {
return; return;
} }
var n = href.match(new RegExp('^https?\\://([0-9a-z-]+)\\.point\\.im/$', 'i')); var matches = href.match(regex);
if (n == null) { if (matches == null) {
return; return;
} }
var this_user_name = n[1].toLowerCase(); var this_user_name = matches[1].toLowerCase();
if (typeof(items[this_user_name]) == 'undefined') { if (typeof(items[this_user_name]) == 'undefined') {
return; return;
} }
@ -1297,11 +1272,15 @@ function hints_save_new_hint(username, new_hint) {
*/ */
function set_comments_refresh_tick(current_options) { function set_comments_refresh_tick(current_options) {
// Проверяем, чтобы были баджи // Проверяем, чтобы были баджи
if ($('#main #left-menu #menu-recent .unread').length == 0) { var $left_menu = $('#left-menu');
$('#main #left-menu #menu-recent').append('<span class="unread" style="display: none;">0</span>'); var $menu_recent_posts = $left_menu.find('#menu-recent');
var $menu_recent_comments = $left_menu.find('#menu-comments');
if ($menu_recent_posts.children('.unread').length == 0) {
$menu_recent_posts.append('<span class="unread" style="display: none;">0</span>');
} }
if ($('#main #left-menu #menu-comments .unread').length == 0) { if ($menu_recent_comments.children('.unread').length == 0) {
$('#main #left-menu #menu-comments').append('<span class="unread" style="display: none;">0</span>'); $menu_recent_comments.append('<span class="unread" style="display: none;">0</span>');
} }
// Ставим тик // Ставим тик
@ -1331,78 +1310,72 @@ var window_focused = true;
// Очищаем [0; 0] // Очищаем [0; 0]
function set_comments_refresh_clear_title_marks() { function set_comments_refresh_clear_title_marks() {
var new_title = document.title.replace(new RegExp('^\\[[0-9]+\\; [0-9]+\\] '), ''); document.title = document.title.replace(new RegExp('^\\[[0-9]+\\; [0-9]+\\] '), '');
document.title = new_title;
window_focused = true; window_focused = true;
} }
// Проверка обновления комментариев, обновляется по крону // Проверка обновления комментариев, обновляется по крону
function comments_count_refresh_tick(current_options) { function comments_count_refresh_tick(current_options) {
$('#debug_iframe').remove(); $('#pp-iframe-unread-refresh').remove();
var iframe = document.createElement('iframe'); var iframe = document.createElement('iframe');
document.body.appendChild(iframe); document.body.appendChild(iframe);
$(iframe).on('load', function() { $(iframe)
var a = $(iframe.contentDocument.body).find('#main #left-menu #menu-recent .unread'); .on('load', function() {
var b = $(iframe.contentDocument.body).find('#main #left-menu #menu-comments .unread'); var a = $(iframe.contentDocument.body).find('#main #left-menu #menu-recent .unread');
var count_recent = (a.length == 0) ? 0 : parseInt(a.text()); var b = $(iframe.contentDocument.body).find('#main #left-menu #menu-comments .unread');
var count_comments = (b.length == 0) ? 0 : parseInt(b.text()); var count_recent = (a.length == 0) ? 0 : parseInt(a.text());
var count_comments = (b.length == 0) ? 0 : parseInt(b.text());
console.log('Comments: %d, Recent: %d', count_comments, count_recent); console.log('Comments: %d, Recent: %d', count_comments, count_recent);
if (count_recent > 0) {
if (parseInt($('#main #left-menu #menu-recent .unread').text()) != count_recent) { var $menu = $('#left-menu');
$('#main #left-menu #menu-recent .unread').text(count_recent).show().css({ var $menu_posts = $menu.children('#menu-recent');
'background-color': '#f2ebee', var $menu_posts_unread = $menu_posts.children('span.unread');
'color': '#7c3558' var $menu_comments = $menu.children('#menu-comments');
}); var $menu_comments_unread = $menu_comments.children('span.unread');
setTimeout(function() {
$('#main #left-menu #menu-recent .unread').css({ if (count_recent > 0) {
'background-color': '', if (parseInt($menu_posts_unread.text()) != count_recent) {
'color': '' $menu_posts_unread.text(count_recent).show().addClass('pp-left-menu-refreshed');
}); setTimeout(function() {
}, 15000); $menu_posts_unread.removeClass('pp-left-menu-refreshed');
}, 15000);
}
} else {
$menu_posts_unread.text('0').hide();
} }
} else {
$('#main #left-menu #menu-recent .unread').text('0').hide();
}
if (count_comments > 0) { if (count_comments > 0) {
if (parseInt($('#main #left-menu #menu-comments .unread').text()) != count_comments) { if (parseInt($menu_comments_unread.text()) != count_comments) {
$('#main #left-menu #menu-comments .unread').text(count_comments).show().css({ $menu_comments_unread.text(count_comments).show().addClass('pp-left-menu-refreshed');
'background-color': '#f2ebee', setTimeout(function() {
'color': '#7c3558' $menu_comments_unread.removeClass('pp-left-menu-refreshed');
}); }, 15000);
setTimeout(function() { }
$('#main #left-menu #menu-comments .unread').css({ } else {
'background-color': '', $menu_comments_unread.text('0').hide();
'color': ''
});
}, 15000);
} }
} else {
$('#main #left-menu #menu-comments .unread').text('0').hide();
}
if ((current_options.is('option_other_comments_count_refresh_title')) && if ((current_options.is('option_other_comments_count_refresh_title')) && (!window_focused)) {
(!window_focused)) { var new_title = document.title.replace(new RegExp('^\\[[0-9]+\\; [0-9]+\\] '), '');
var new_title = document.title.replace(new RegExp('^\\[[0-9]+\\; [0-9]+\\] '), ''); if ((count_recent > 0) || (count_comments > 0)) {
if ((count_recent > 0) || (count_comments > 0)) { new_title = '[' + count_recent + '; ' + count_comments + '] ' + new_title;
new_title = '[' + count_recent + '; ' + count_comments + '] ' + new_title; }
document.title = new_title;
} }
document.title = new_title;
}
$('#debug_iframe').remove(); $('#pp-iframe-unread-refresh').remove();
}).attr({ })
// Из-за Same Origin'а я дёргаю несуществующую страницу на том же домене, чтобы получить баджи и, .attr({
// в то же время не прочитать новые сообщения в ленте, которые могли появиться, если их написал // Из-за Same Origin'а я дёргаю несуществующую страницу на том же домене, чтобы получить баджи и,
// этот пользователь // в то же время не прочитать новые сообщения в ленте, которые могли появиться, если их написал
'src': '//' + document.domain + '/?tag=' + Math.random(), // этот пользователь
'id': 'debug_iframe' 'src': '//' + document.domain + '/?tag=' + Math.random(),
}).css({ 'id': 'pp-iframe-unread-refresh'
'width': '600px', })
'height': '300px' ;
}).hide();
} }
/** /**
@ -1451,13 +1424,15 @@ function twitter_tweet_embedding_wait_for_ready_injected() {
* Парсим все ссылки. Эта функция запускается из page scope * Парсим все ссылки. Эта функция запускается из page scope
*/ */
function twitter_tweet_embedding_parse_links() { function twitter_tweet_embedding_parse_links() {
var regex = new RegExp('^https?://(www\\.)?twitter\\.com/[^/]+/status/([0-9]+)', 'i');
// Обрабатываем все твиты // Обрабатываем все твиты
var twitter_tweet_count = 0; var twitter_tweet_count = 0;
$('.post-content a:not(.booru_pic)').each(function(num, obj) { $('.post-content a:not(.booru_pic)').each(function(num, obj) {
var href = obj.href; var href = obj.href;
var n; var n;
if (n = href.match(new RegExp('^https?://(www\\.)?twitter\\.com/[^/]+/status/([0-9]+)', 'i'))) { if (n = href.match(regex)) {
var tweet = document.createElement('div'); var tweet = document.createElement('div');
$(tweet).attr({ $(tweet).attr({
'id': 'tweet-' + twitter_tweet_count, 'id': 'tweet-' + twitter_tweet_count,
@ -1508,11 +1483,10 @@ function instagram_posts_embedding_init(options) {
id: 'instagram-' + num, id: 'instagram-' + num,
href: 'http://instagram.com/p/' + matches[2] + '/media/?size=l', href: 'http://instagram.com/p/' + matches[2] + '/media/?size=l',
title: response.title, title: response.title,
traget: '_blank',
'data-fancybox-group': (options.is('option_fancybox_bind_images_to_one_flow')) ? 'one_flow_gallery' : '', 'data-fancybox-group': (options.is('option_fancybox_bind_images_to_one_flow')) ? 'one_flow_gallery' : '',
'data-fancybox-title': (options.is('option_fancybox_smart_hints')) ? response.title : ''
}) })
.append($img); .append($img)
;
$link.before($imgLink); $link.before($imgLink);

View File

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Point+", "name": "Point+",
"version": "1.40.1", "version": "1.42.1",
"default_locale": "ru", "default_locale": "ru",
"author": "__MSG_ext_author__", "author": "__MSG_ext_author__",
"homepage_url": "https://bitbucket.org/skobkin/chrome_point_plus", "homepage_url": "https://bitbucket.org/skobkin/chrome_point_plus",
@ -27,7 +27,7 @@
{ {
"matches": ["http://*.point.im/*", "https://*.point.im/*"], "matches": ["http://*.point.im/*", "https://*.point.im/*"],
"js": [ "js": [
"vendor/jquery/jquery.min.js", "vendor/jquery/dist/jquery.min.js",
"js/options-manager.js", "js/options-manager.js",
"js/message-sender.js", "js/message-sender.js",

View File

@ -11,10 +11,10 @@ function Booru($links, options) {
} }
/** /**
* Откуда тянуть картинки * Base URL of gelbooru picture API (@NokitaKaze)
* @type {String} * @type {String}
*/ */
Booru.baseUrl = 'https://api.kanaria.ru/point/get_booru_picture.php'; Booru.baseUrl = 'https://evidell.xyz/get_booru_picture.php';
/* jshint maxlen:false */ /* jshint maxlen:false */
Booru.services = { Booru.services = {

View File

@ -40,11 +40,6 @@
<input type="checkbox" name="option-fancybox-bind-images-to-one-flow"> <input type="checkbox" name="option-fancybox-bind-images-to-one-flow">
<span data-i18n="option_fancybox_bind_images_to_one_flow"></span> <span data-i18n="option_fancybox_bind_images_to_one_flow"></span>
</label> </label>
<label class="option-node">
<input type="checkbox" name="option-fancybox-smart-hints">
<span data-i18n="option_fancybox_smart_hints"></span>
</label>
</div> </div>
<label class="option-node"> <label class="option-node">

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,6 +1,6 @@
{ {
"name": "chrome-point-plus", "name": "chrome-point-plus",
"version": "1.40.1", "version": "1.42.1",
"description": "Chrome extension for point.im", "description": "Chrome extension for point.im",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {