Skip to content

Instantly share code, notes, and snippets.

@t-kashima
Last active December 23, 2015 04:39
Show Gist options
  • Save t-kashima/6581646 to your computer and use it in GitHub Desktop.
Save t-kashima/6581646 to your computer and use it in GitHub Desktop.
ZOZOPocket (ZOZOTOWN MEMO SYSTEM)
<script type="text/javascript" src="utility.js"></script>
<script type="text/javascript" src="background.js"></script>
// Listの初期化
// clearGidList();
// clearGoodsList();
updateBadge();
chrome.runtime.onConnect.addListener(function(port) {
console.assert(port.name === 'addPocket');
port.onMessage.addListener(function(msg) {
var goodsInfo = msg.goods_info;
if (goodsInfo == null) {
return;
}
// console.log(goodsInfo);
console.log('GID:' + goodsInfo.gid);
// GIDを記録する
// addGid(gid);
var isAddGoodsInfo = addGoodsInfo(goodsInfo);
console.log('Add goods info:' + isAddGoodsInfo);
updateBadge();
});
});
#zozopocket {
margin: 10px 0px 20px;
padding: 0px;
}
(function() {
var matches = location.href.match(/^http:\/\/zozotown\.com\/.+?gid=/);
// ZOZOTOWNのページではない時は処理をやめる
if (matches === null || matches.length < 1) {
return;
}
var elementInfoBlock = document.querySelector('.infoBlock');
var elementItemImage = document.querySelector('#Item_Info_img_info');
var elementCategories = document.querySelectorAll('.contbox ul.lineNavi li');
var elementPrice = document.querySelector('.price span');
if (elementPrice === null) {
var elementPrices = document.querySelectorAll('.saleBox .priceDown .special span');
elementPrice = elementPrices[elementPrices.length - 1];
}
// var elementCategory = elementCategories[elementCategories.length - 1];
var div = document.createElement('div');
div.id = 'zozopocket';
var button = document.createElement('button');
button.textContent = 'ZOZOPOCKETに追加する';
button.addEventListener('click', function(event) {
var goodsInfo = getGoodsInfo();
addPocket(goodsInfo);
}, true);
div.appendChild(button);
elementInfoBlock.appendChild(div);
function getGoodsInfo() {
var gid = getScrape(/gid=(\d+)/, location.href);
var image = getScrape(/url\((.+?)\?w=/, elementItemImage.style.cssText);
var brand = getScrape(/ブランド:(.+?)\s/,
elementInfoBlock.textContent);
var price = elementPrice.textContent;
var category = '';
for (var i = 0; i < elementCategories.length; i++) {
var str = elementCategories[i].textContent;
str = str.replace('>', '');
category += str;
if (i != (elementCategories.length - 1)) {
category += ' / ';
}
}
console.log('GID=' + gid + ', URL=' + image + ', Brand=' +
brand + ', Price=' + price + ', Category=' +
category);
var goodsInfo = new Object();
goodsInfo['gid'] = gid;
goodsInfo['image'] = image;
goodsInfo['brand'] = brand;
goodsInfo['price'] = price;
goodsInfo['category'] = category;
return goodsInfo;
}
}).call(this);
function addPocket(goodsInfo) {
console.log('add pocket GID:' + goodsInfo.gid);
var port = chrome.runtime.connect({name: 'addPocket'});
port.postMessage({goods_info: goodsInfo});
}
function addPocketByGid(gid) {
console.log('add pocket GID:' + gid);
var port = chrome.runtime.connect({name: 'addPocketByGid'});
port.postMessage({gid: gid});
}
function getScrape(pattern, str) {
var matches = str.match(pattern);
var matchStr = null;
if (typeof(matches) == 'object' && matches.length > 1) {
matchStr = matches[1];
}
return matchStr;
}
{
"name": "ZOZOPOCKET",
"version": "1.0.0",
"manifest_version": 2,
"description": "Pocket for ZOZOTOWN",
"browser_action": {
"default_icon": "icon.png",
"default_title": "ZOZOPOCKET",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"css": ["content_script.css"],
"js": ["content_script.js"]
}
],
"background": {
"page": "background.html"
},
"permissions": ["background"]
}
body {
width: 300px;
}
ul {
list-style-type: none;
margin: 0px;
padding: 0px;
}
.goods_operator_list {
margin-bottom: 10px;
border-bottom: 1px solid #BBB;
}
.delete_all_button:focus {
outline: none;
}
.delete_all_button {
border: none;
background: none;
color: #BBB;
font-size: 12px;
margin: 0px;
line-height: 10px;
cursor: pointer;
padding: 0px;
}
.delete_all_button:hover {
color: #222;
}
.goods_info {
margin: 7px 0px;
}
.goods_info_wrapper {
display: -webkit-box;
height: 60px;
}
.goods_info_detail {
padding-top: 3px;
margin-left: 10px;
font-size: 12px;
}
.goods_image {
max-height: 60px;
}
.goods_info_wrapper:hover {
background: #DEDEDE;
cursor: pointer;
}
a {
text-decoration: none;
color: #222;
}
a:focus {
outline: none;
}
.goods_delete_button {
border: none;
background: none;
color: #BBB;
font-size: 12px;
margin: 0px;
line-height: 10px;
cursor: pointer;
}
.goods_delete_button:hover {
color: #222;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ZOZOPOCKET</title>
<link rel="stylesheet" type="text/css" href="popup.css" />
</head>
<body>
<ul class="goods_operator_list">
<li>
<button class="delete_all_button">delete all</button>
</li>
</ul>
<ul class="goods_list"></ul>
<script src="utility.js" type="text/javascript"></script>
<script src="popup.js" type="text/javascript"></script>
</body>
</html>
// 商品情報リストを表示する場所を取得する
var elementGoodsList = document.querySelector('.goods_list');
var elementDeleteAllButton = document.querySelector('.delete_all_button');
elementDeleteAllButton.addEventListener('click', function() {
clearGoodsInfo();
updateGoodsList();
}, true);
function updateGoodsList() {
// 既に表示している要素の削除
elementGoodsList.innerHTML = '';
// バッジを更新する
updateBadge();
// 商品情報リストを取得する
var goodsList = getGoodsList();
// 商品情報リストのテンプレートを取得する
var template = getElementGoodsInfo();
// 商品情報を表示する
for (var i = 0; i < goodsList.length; i++) {
var elementGoodsInfo = template.cloneNode(true);
var goodsInfo = goodsList[i];
elementGoodsInfo.querySelector('.goods_link').href = getGoodsUrl(goodsInfo.gid);
elementGoodsInfo.querySelector('.goods_image').src = goodsInfo.image;
elementGoodsInfo.querySelector('.goods_price').textContent = goodsInfo.price;
elementGoodsInfo.querySelector('.goods_brand').textContent = goodsInfo.brand;
elementGoodsInfo.querySelector('.goods_category').textContent = goodsInfo.category;
var elementGoodsDeleteButton = elementGoodsInfo.querySelector('.goods_delete_button');
elementGoodsDeleteButton.setAttribute('data-gid', goodsInfo.gid);
elementGoodsDeleteButton.addEventListener('click', deleteGoodsInfo, true);
elementGoodsList.appendChild(elementGoodsInfo);
}
}
updateGoodsList();
/**
* リスト表示のためのテンプレートを生成する
*
* @return DOM リスト
*/
function getElementGoodsInfo() {
var goodsInfo = document.createElement('li');
goodsInfo.classList.add('goods_info');
var goodsInfoWrapper = document.createElement('div');
goodsInfoWrapper.classList.add('goods_info_wrapper');
goodsInfo.appendChild(goodsInfoWrapper);
var goodsLink = document.createElement('a');
goodsLink.classList.add('goods_link');
goodsLink.target = '_blank';
goodsInfoWrapper.appendChild(goodsLink);
var goodsImage = document.createElement('img');
goodsImage.classList.add('goods_image');
goodsLink.appendChild(goodsImage);
var goodsInfoDetail = document.createElement('div');
goodsInfoDetail.classList.add('goods_info_detail');
goodsLink.appendChild(goodsInfoDetail);
var goodsBrand = document.createElement('div');
goodsBrand.classList.add('goods_brand');
goodsInfoDetail.appendChild(goodsBrand);
var goodsPrice = document.createElement('div');
goodsPrice.classList.add('goods_price');
goodsInfoDetail.appendChild(goodsPrice);
var goodsCategory = document.createElement('div');
goodsCategory.classList.add('goods_category');
goodsInfoDetail.appendChild(goodsCategory);
var goodsDeleteButton = document.createElement('a');
goodsDeleteButton.classList.add('goods_delete_button');
goodsDeleteButton.textContent = 'delete';
goodsInfo.appendChild(goodsDeleteButton);
return goodsInfo;
}
function deleteGoodsInfo(event) {
var gid = event.currentTarget.getAttribute('data-gid');
console.log('Delete gid:' + gid);
// 商品情報リストから指定GIDの商品情報を削除
var isDelete = deleteGoodsList(gid);
console.log('is delete:' + isDelete);
// 表示を更新する
updateGoodsList();
}
// 保存するローカルストレージの鍵
const GID_LIST_KEY = 'zozopocket_gid_list';
const GOODS_LIST_KEY = 'zozopocket_goods_list';
const BASE_GOODS_URL = 'http://zozotown.com/?c=gr&gid=';
// Arrayにその要素が含まれているかの判定を追加する
Array.prototype.contains = function(value) {
for (var i = 0; i < this.length; i++) {
if (this[i] === value) {
return true;
}
}
return false;
}
// Arrayの要素を見つける
Array.prototype.find = function(value) {
for (var i = 0; i < this.length; i++) {
if (this[i] === value) {
return i;
}
}
return -1;
}
/**
* GIDのリストを取得する
*
* @return GIDのリスト
*/
function getGidList() {
var gidList = localStorage[GID_LIST_KEY];
if (typeof(gidList) === 'undefined') {
return undefined;
}
return JSON.parse(gidList);
}
function getGoodsList() {
var goodsList = localStorage[GOODS_LIST_KEY];
if (typeof(goodsList) === 'undefined') {
return undefined;
}
return JSON.parse(goodsList);
}
function deleteGidList(gid) {
var gidList = getGidList();
if (typeof(gidList) === 'undefined') {
return false;
}
var deleteIndex = gidList.find(gid);
if (deleteIndex === -1 ||
deleteIndex >= gidList.length) {
return false;
}
gidList.splice(deleteIndex, 1);
localStorage[GID_LIST_KEY] = JSON.stringify(gidList);
return true;
}
function deleteGoodsList(gid) {
var isDelete = deleteGidList(gid);
if (isDelete === false) {
return false;
}
var goodsList = getGoodsList();
if (typeof(goodsList) === 'undefined') {
return false;
}
for (var i = 0; i < goodsList.length; i++) {
var goodsInfo = goodsList[i];
if (goodsInfo.gid === gid) {
goodsList.splice(i, 1);
localStorage[GOODS_LIST_KEY] = JSON.stringify(goodsList);
return true;
}
}
return false;
}
function clearGidList() {
delete localStorage[GID_LIST_KEY];
}
function clearGoodsList() {
delete localStorage[GOODS_LIST_KEY];
}
function clearGoodsInfo() {
clearGidList();
clearGoodsList();
}
/**
* GIDをリストに追加する
*
* @param gid 追加するGID
* @return bool 追加できたかどうか
*/
function addGid(gid) {
var gidList = getGidList();
if (typeof(gidList) === 'undefined') {
gidList = new Array();
}
if (gidList.contains(gid) == true) {
return false;
} else {
gidList.push(gid);
}
localStorage[GID_LIST_KEY] = JSON.stringify(gidList);
return true
}
function addGoodsInfo(goodsInfo) {
var isAdd = addGid(goodsInfo.gid);
if (isAdd === false) {
return false;
}
var goodsList = getGoodsList();
if (typeof(goodsList) === 'undefined') {
goodsList = new Array();
}
goodsList.push(goodsInfo);
localStorage[GOODS_LIST_KEY] = JSON.stringify(goodsList);
return true;
}
/**
* バッジを更新する
*/
function updateBadge() {
var gidList = getGidList();
if (typeof(gidList) === 'undefined') {
chrome.browserAction.setBadgeText({text: ''});
return;
}
// バッジ数を変更する
chrome.browserAction.setBadgeText({text: "" + gidList.length});
}
function getPageContent(url) {
console.log('Get page url: ' + url);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
}
}
xhr.open('GET', url, true);
xhr.send();
}
function getPageContentByGid(gid) {
getPageContent(BASE_GOODS_URL + gid);
}
function getGoodsUrl(gid) {
return BASE_GOODS_URL+ gid;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment