Skip to content

Commit

Permalink
Merge pull request #15 from io-monad/publish-update
Browse files Browse the repository at this point in the history
feat(publish): Publishing now updates opened tabs if exist
  • Loading branch information
io-monad committed May 2, 2016
2 parents bf7c291 + f480a35 commit b26d3c4
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 81 deletions.
3 changes: 3 additions & 0 deletions app/_locales/ja/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
"wentWrong": {
"message": "申し訳ございません。問題が発生しました。"
},
"confirmPublishOverwrite": {
"message": "小説の入力内容が変更されています。\n上書きしてもよろしいですか?"
},

"options": {
"message": "設定"
Expand Down
50 changes: 32 additions & 18 deletions app/scripts/lib/sites/kakuyomu/publish.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from "lodash";
import { translate } from "@io-monad/chrome-util";
import moment from "../../util/moment";
import openPage from "../../util/open-page";
import KakuyomuURL from "./url";
Expand All @@ -12,7 +13,7 @@ import KakuyomuURL from "./url";
export default function publish(publication) {
const url = getURL(publication);
const code = getCode(publication);
return openPage(url, code);
return openPage(url, code, { update: true });
}

function getURL(pub) {
Expand All @@ -24,31 +25,44 @@ function getURL(pub) {
}

function getCode(pub) {
const title = JSON.stringify(pub.title || "");
const body = JSON.stringify(pub.body || "");
let code = `
const embedPub = {
title: pub.title || "",
body: pub.body || "",
};
if (pub.time) {
const time = moment(pub.time).tz("Asia/Tokyo");
embedPub.date = time.format("YYYY-MM-DD");
embedPub.time = time.format("HH:mm");
}
return `
var pub = ${JSON.stringify(embedPub)};
var form = document.getElementById("episode-editForm");
var lastPub = window.novelousLastPublication || { title: "", body: "" };
if (form.title.value !== lastPub.title || form.body.value !== lastPub.body) {
if (!confirm(${JSON.stringify(translate("confirmPublishOverwrite"))})) {
return;
}
}
var change = document.createEvent("HTMLEvents");
change.initEvent("change", true, true);
form.title.value = ${title};
form.title.value = pub.title;
form.title.dispatchEvent(change);
form.body.value = ${body};
form.body.value = pub.body;
form.body.dispatchEvent(change);
`;
if (pub.time) {
const time = moment(pub.time).tz("Asia/Tokyo");
const dateValue = JSON.stringify(time.format("YYYY-MM-DD"));
const timeValue = JSON.stringify(time.format("HH:mm"));
code += `
document.querySelector(".js-reservation-panel-button").click();
if (pub.date && pub.time) {
var button = document.querySelector(".js-reservation-panel-button");
if (!/isPanelShown/.test(button.className)) {
button.click();
}
document.getElementById("reservationInput-reserved").click();
form.reservation_date.value = ${dateValue};
form.reservation_time.value = ${timeValue};
`;
}
form.reservation_date.value = pub.date;
form.reservation_time.value = pub.time;
}
return code;
window.novelousLastPublication = pub;
`;
}
48 changes: 30 additions & 18 deletions app/scripts/lib/sites/narou/publish.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from "lodash";
import { translate } from "@io-monad/chrome-util";
import moment from "../../util/moment";
import openPage from "../../util/open-page";
import NarouURL from "./url";
Expand All @@ -12,7 +13,7 @@ import NarouURL from "./url";
export default function publish(publication) {
const url = getURL(publication);
const code = getCode(publication);
return openPage(url, code);
return openPage(url, code, { update: true });
}

function getURL(pub) {
Expand All @@ -24,25 +25,36 @@ function getURL(pub) {
}

function getCode(pub) {
const title = JSON.stringify(pub.title || "");
const body = JSON.stringify(pub.body || "");
let code = `
var form = document.getElementById("manage_form");
form.subtitle.value = ${title};
form.novel.value = ${body};
`;

const embedPub = {
title: pub.title || "",
body: pub.body || "",
};
if (pub.time) {
const time = moment(pub.time).tz("Asia/Tokyo");
const monthValue = JSON.stringify(time.format("YYYY-MM"));
const dayValue = JSON.stringify(time.format("D"));
const hourValue = JSON.stringify(time.format("H"));
code += `
form.month.value = ${monthValue};
form.day.value = ${dayValue};
form.hour.value = ${hourValue};
`;
embedPub.month = time.format("YYYY-MM");
embedPub.day = time.format("D");
embedPub.hour = time.format("H");
}
return `
var pub = ${JSON.stringify(embedPub)};
var form = document.getElementById("manage_form");
return code;
var lastPub = window.novelousLastPublication || { title: "", body: "" };
if (form.subtitle.value !== lastPub.title || form.novel.value !== lastPub.body) {
if (!confirm(${JSON.stringify(translate("confirmPublishOverwrite"))})) {
return;
}
}
form.subtitle.value = pub.title;
form.novel.value = pub.body;
if (pub.month && pub.day) {
form.month.value = pub.month;
form.day.value = pub.day;
form.hour.value = pub.hour;
}
window.novelousLastPublication = pub;
`;
}
49 changes: 39 additions & 10 deletions app/scripts/lib/util/open-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,49 @@
*
* @param {string} url - A URL of the opening page.
* @param {string} code - A code to be executed on the page.
* @param {Object} [options] - Options.
* @param {boolean} [options.update=false] - Set this to `true` for updating existing tab.
* @return {Promise}
*/
export default function openPage(url, code) {
return new Promise((resolve, reject) => {
chrome.tabs.create({ url }, (tab) => {
const wrapped = wrapInjectCode(code);
chrome.tabs.executeScript(tab.id, { code: wrapped }, (results) => {
// results = [error] or [null]
if (results.length > 0 && results[0]) {
reject(results[0]);
export default function openPage(url, code, options) {
options = options || {};
return new Promise(resolve => {
if (options.update) {
chrome.tabs.query({ url }, (tabs) => {
if (tabs.length > 0) {
chrome.tabs.update(tabs[0].id, { active: true }, tab => {
resolve(executeCode(tab, code));
});
} else {
resolve();
chrome.tabs.create({ url }, tab => {
resolve(executeCode(tab, code));
});
}
});
} else {
chrome.tabs.create({ url }, tab => {
resolve(executeCode(tab, code));
});
}
});
}

/**
* @param {chrome~Tab} tab
* @param {string} code
* @return {Promise}
* @private
*/
function executeCode(tab, code) {
return new Promise((resolve, reject) => {
const wrapped = wrapInjectCode(code);
chrome.tabs.executeScript(tab.id, { code: wrapped }, (results) => {
// results = [error] or [null]
if (results.length > 0 && results[0]) {
reject(results[0]);
} else {
resolve();
}
});
});
}
Expand All @@ -35,6 +64,6 @@ function wrapInjectCode(code) {
return e.message || e;
}
return null;
})();
}());
`;
}
69 changes: 52 additions & 17 deletions test/lib/sites/kakuyomu/publish-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,69 @@ import { _, assert, factory } from "../../../common";
import publish from "../../../../app/scripts/lib/sites/kakuyomu/publish";

describe("KakuyomuPublish", () => {
it("publishes novel to sites", () => {
const pub = factory.buildSync("publication", {
let pub;
let publishUrl;
before(() => {
pub = factory.buildSync("publication", {
sites: {
kakuyomu: { novelId: "12341234" },
},
});
chrome.tabs.create.callsArgWithAsync(1, { id: 123 });
chrome.tabs.executeScript.callsArgWithAsync(2, [null]);
publishUrl = `https://kakuyomu.jp/my/works/${pub.sites.kakuyomu.novelId}/episodes/new`;
});

it("opens a new tab with publication contents", () => {
chrome.tabs.query.yieldsAsync([]);
chrome.tabs.create.yieldsAsync({ id: 123 });
chrome.tabs.executeScript.yieldsAsync([null]);

return publish(pub).then(() => {
assert(chrome.tabs.create.calledOnce);
assert.deepEqual(chrome.tabs.create.args[0][0], {
url: `https://kakuyomu.jp/my/works/${pub.sites.kakuyomu.novelId}/episodes/new`,
assert(chrome.tabs.query.calledOnce === true);
assert.deepEqual(chrome.tabs.query.args[0][0], { url: publishUrl });

assert(chrome.tabs.create.calledOnce === true);
assert.deepEqual(chrome.tabs.create.args[0][0], { url: publishUrl });

assert(chrome.tabs.executeScript.calledOnce === true);
assert(chrome.tabs.executeScript.args[0][0] === 123);
assert(_.isString(chrome.tabs.executeScript.args[0][1].code));

const code = chrome.tabs.executeScript.args[0][1].code;
const embedPub = JSON.parse(code.match(/var pub = (.+?);/)[1]);
assert.deepEqual(embedPub, {
title: pub.title,
body: pub.body,
date: "2016-03-01",
time: "11:34",
});
assert(chrome.tabs.executeScript.calledOnce);
});
});

it("updates an existing tab with publication contents", () => {
chrome.tabs.query.yieldsAsync([{ id: 123 }]);
chrome.tabs.update.yieldsAsync({ id: 123 });
chrome.tabs.executeScript.yieldsAsync([null]);

return publish(pub).then(() => {
assert(chrome.tabs.query.calledOnce === true);
assert.deepEqual(chrome.tabs.query.args[0][0], { url: publishUrl });

assert(chrome.tabs.update.calledOnce === true);
assert(chrome.tabs.update.args[0][0] === 123);
assert.deepEqual(chrome.tabs.update.args[0][1], { active: true });

assert(chrome.tabs.executeScript.calledOnce === true);
assert(chrome.tabs.executeScript.args[0][0] === 123);
assert(_.isString(chrome.tabs.executeScript.args[0][1].code));

const code = chrome.tabs.executeScript.args[0][1].code;
const formValue = (name) => {
const re = new RegExp(`form\\.${name}\\.value = (.+?);`);
return JSON.parse(code.match(re)[1]);
};

assert(formValue("title") === pub.title);
assert(formValue("body") === pub.body);
assert(formValue("reservation_date") === "2016-03-01");
assert(formValue("reservation_time") === "11:34");
const embedPub = JSON.parse(code.match(/var pub = (.+?);/)[1]);
assert.deepEqual(embedPub, {
title: pub.title,
body: pub.body,
date: "2016-03-01",
time: "11:34",
});
});
});
});
72 changes: 54 additions & 18 deletions test/lib/sites/narou/publish-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,67 @@ import { _, assert, factory } from "../../../common";
import publish from "../../../../app/scripts/lib/sites/narou/publish";

describe("NarouPublish", () => {
it("publishes novel to sites", () => {
const pub = factory.buildSync("publication");
chrome.tabs.create.callsArgWithAsync(1, { id: 123 });
chrome.tabs.executeScript.callsArgWithAsync(2, [null]);
let pub;
let publishUrl;
before(() => {
pub = factory.buildSync("publication");
publishUrl = `http://syosetu.com/usernovelmanage/ziwainput/ncode/${pub.sites.narou.novelId}/`;
});

it("opens a new tab with publication contents", () => {
chrome.tabs.query.yieldsAsync([]);
chrome.tabs.create.yieldsAsync({ id: 123 });
chrome.tabs.executeScript.yieldsAsync([null]);

return publish(pub).then(() => {
assert(chrome.tabs.create.calledOnce);
assert.deepEqual(chrome.tabs.create.args[0][0], {
url: `http://syosetu.com/usernovelmanage/ziwainput/ncode/${pub.sites.narou.novelId}/`,
assert(chrome.tabs.query.calledOnce === true);
assert.deepEqual(chrome.tabs.query.args[0][0], { url: publishUrl });

assert(chrome.tabs.create.calledOnce === true);
assert.deepEqual(chrome.tabs.create.args[0][0], { url: publishUrl });

assert(chrome.tabs.executeScript.calledOnce === true);
assert(chrome.tabs.executeScript.args[0][0] === 123);
assert(_.isString(chrome.tabs.executeScript.args[0][1].code));

const code = chrome.tabs.executeScript.args[0][1].code;
const embedPub = JSON.parse(code.match(/var pub = (.+?);/)[1]);
assert.deepEqual(embedPub, {
title: pub.title,
body: pub.body,
month: "2016-03",
day: "1",
hour: "11",
});
assert(chrome.tabs.executeScript.calledOnce);
});
});

it("updates an existing tab with publication contents", () => {
chrome.tabs.query.yieldsAsync([{ id: 123 }]);
chrome.tabs.update.yieldsAsync({ id: 123 });
chrome.tabs.executeScript.yieldsAsync([null]);

return publish(pub).then(() => {
assert(chrome.tabs.query.calledOnce === true);
assert.deepEqual(chrome.tabs.query.args[0][0], { url: publishUrl });

assert(chrome.tabs.update.calledOnce === true);
assert(chrome.tabs.update.args[0][0] === 123);
assert.deepEqual(chrome.tabs.update.args[0][1], { active: true });

assert(chrome.tabs.executeScript.calledOnce === true);
assert(chrome.tabs.executeScript.args[0][0] === 123);
assert(_.isString(chrome.tabs.executeScript.args[0][1].code));

const code = chrome.tabs.executeScript.args[0][1].code;
const formValue = (name) => {
const re = new RegExp(`form\\.${name}\\.value = (.+?);`);
return JSON.parse(code.match(re)[1]);
};

assert(formValue("subtitle") === pub.title);
assert(formValue("novel") === pub.body);
assert(formValue("month") === "2016-03");
assert(formValue("day") === "1");
assert(formValue("hour") === "11");
const embedPub = JSON.parse(code.match(/var pub = (.+?);/)[1]);
assert.deepEqual(embedPub, {
title: pub.title,
body: pub.body,
month: "2016-03",
day: "1",
hour: "11",
});
});
});
});

0 comments on commit b26d3c4

Please sign in to comment.