Last active
December 23, 2015 04:39
-
-
Save t-kashima/6581646 to your computer and use it in GitHub Desktop.
ZOZOPocket (ZOZOTOWN MEMO SYSTEM)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type="text/javascript" src="utility.js"></script> | |
<script type="text/javascript" src="background.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#zozopocket { | |
margin: 10px 0px 20px; | |
padding: 0px; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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"] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 商品情報リストを表示する場所を取得する | |
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(); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 保存するローカルストレージの鍵 | |
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