Skip to content

Commit

Permalink
feat: ページ全体を一括で保存するボタンを配置 (#254)
Browse files Browse the repository at this point in the history
* refactor: 関数名の修正とコメントの追加

* feat: ページ全体を一括で保存するボタンを配置

* fix: 外部の画像を参照しているblogタイプコンテンツでエラーが出るのを修正
  • Loading branch information
mnao305 authored Jul 3, 2022
1 parent d4def57 commit 6892d12
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 27 deletions.
41 changes: 20 additions & 21 deletions src/content/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { browser } from 'webextension-polyfill-ts'
import { PostData } from '../types'
import { Backnumber } from '../types/backnumber'
import { fetchBacknumberData } from './modules/backnumberPage'
import { injectBtn } from './modules/dom'
import { injectGalleryAllDlBtn, injectPageAllContentsDlBtn } from './modules/dom'
import { fileDownload } from './modules/download'
import { getImgList, getPhotoContents } from './modules/img'
import { downloadEverythingFromPost, fetchPostData } from './modules/postPage'
Expand Down Expand Up @@ -65,28 +65,27 @@ const elementIdTocontentId = (id: string) => {
}

const main = () => {
const target = document.getElementById('page')
if (!target) return
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if ((mutation.target as HTMLElement).className === 'content-block type-photo-gallery ng-scope') {
const elId = (mutation.target as HTMLElement).closest('.post-content-inner')?.id
if (elId) {
const contentId = elementIdTocontentId(elId)
injectBtn((mutation.target as HTMLElement), contentId)
observer.disconnect()
}
}
})
})
/**
* ページ読み込み完了後に発火する初期化処理
*/
window.onload = () => {
// 投稿ページ全体一括保存ボタン作成
const postBtnEl = document.getElementsByClassName('post-btns')
if (postBtnEl.length > 0) {
injectPageAllContentsDlBtn((postBtnEl[0] as HTMLElement))
}

const config = {
characterData: false,
childList: true,
subtree: true
// ギャラリーの一括保存ボタン作成
const galleryElements = document.getElementsByClassName('content-block type-photo-gallery ng-scope')
for (let i = 0; i < galleryElements.length; i++) {
const element = galleryElements[i] as HTMLElement
const elId = element.closest('.post-content-inner')?.id
if (elId) {
const contentId = elementIdTocontentId(elId)
injectGalleryAllDlBtn(element, contentId)
}
}
}

observer.observe(target, config)
}
main()

Expand Down
6 changes: 5 additions & 1 deletion src/content/modules/blog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ export const blogDL = (postContent: PostContentBlog, filepath: string): void =>
const blog = json.ops
for (let i = 0; i < blog.length; i++) {
const element = blog[i]
if (typeof element.insert !== 'string') {
if (typeof element.insert !== 'string' && element.insert.fantiaImage) {
// Fantiaの画像
const url = `https://fantia.jp/${element.insert.fantiaImage.original_url}`
fileDownload(url, filepath, element.insert.fantiaImage.id + urlToExt(element.insert.fantiaImage.url))
} else if (typeof element.insert !== 'string' && element.insert.image) {
// 外部を参照している画像
fileDownload(element.insert.image, filepath, String(i) + urlToExt(element.insert.image))
}
}
// TODO: テキストのダウンロード
Expand Down
53 changes: 50 additions & 3 deletions src/content/modules/dom.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import { browser } from 'webextension-polyfill-ts'
import { saveImages } from '../index'
import { downloadEverythingFromPost } from './postPage'

export const btnCreate = (contentId: string): HTMLButtonElement => {
/**
* ダウンロードアイコンを返す
* @param {number} iconSize アイコンサイズをpxの数値で指定する
*/
const createDownloadIcon = (iconSize: number) => {
return (
`<svg style="width:${iconSize}px;height:${iconSize}px;margin-right:5px;" viewBox="0 0 24 24">
<path fill="currentColor" d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" />
</svg>`
)
}

/**
* 画像ギャラリーを一括保存するボタンを作る
*/
const createGalleryAllDlBtn = (contentId: string): HTMLButtonElement => {
const btn = document.createElement('button')
btn.textContent = browser.i18n.getMessage('download_all')
btn.setAttribute('style', 'display: block;margin: 20px auto;padding: 20px 40px;background-color: #22c283;border: none;color: #fff;border-radius: 10px;')
Expand All @@ -10,7 +26,38 @@ export const btnCreate = (contentId: string): HTMLButtonElement => {
return btn
}

export const injectBtn = (el: HTMLElement, contentId: string): void => {
const btn = btnCreate(contentId)
/**
* 画像ギャラリーを一括保存するボタンを配置する
*/
export const injectGalleryAllDlBtn = (el: HTMLElement, contentId: string): void => {
const btn = createGalleryAllDlBtn(contentId)
el.appendChild(btn)
}

/**
* ページコンテンツを全てDLするボタンを作る
*/
const createPageAllContentsDlBtn = (): HTMLButtonElement => {
const btn = document.createElement('button')
btn.innerHTML = `${createDownloadIcon(16)}<span>${browser.i18n.getMessage('download_all')}</span>`
btn.setAttribute('style', 'margin-left: 5px; border: 1px solid #dddddd; background-color: #ffffff; color: #999999; display: inline-flex; align-items: center;')
btn.className = 'btn btn-sm'
btn.onclick = downloadEverythingFromPost

btn.onmouseover = () => {
btn.setAttribute('style', 'margin-left: 5px; border: 1px solid #dddddd; background-color: #ffffff; color: #22c283; display: inline-flex; align-items: center;')
}

btn.onmouseout = () => {
btn.setAttribute('style', 'margin-left: 5px; border: 1px solid #dddddd; background-color: #ffffff; color: #999999; display: inline-flex; align-items: center;')
}
return btn
}

/**
* ページコンテンツを全てDLするボタンを配置する
*/
export const injectPageAllContentsDlBtn = (el: HTMLElement) => {
const btn = createPageAllContentsDlBtn()
el.appendChild(btn)
}
5 changes: 3 additions & 2 deletions src/types/blog.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
interface FantiaImage {
fantiaImage: {
fantiaImage?: {
id: string
url: string
'original_url': string
}
},
image?: string
}

export interface BlogBlock {
Expand Down

0 comments on commit 6892d12

Please sign in to comment.