Здравствуйте. Возникла необходимость сделать расширение для браузера. Как выяснил использовать не опубликованные расширения нельзя, а для публикации необходим аккаунт разработчика. Делал себе кто-нибудь этот аккаунт ?
Читать полностью…Отправь запрос в гпт, только омни или на you com выбери гпт4 турбо, там нужно манифест настроить адекватно, а там уже заниматься функциями
Читать полностью…Привет мододелам. Пытаюсь понять, как ограничить доступ к сайтам, на которых расширение работает.
Пробовал host_permissions или content_scripts.matches, но расширение всё равно срабатывает на всех сайтах. Искал доку в background и action, но там ограничений нет. Единственное, что нашёл, это chrome.action.disable/setIcon - отключает и/или заменяет значок из background.
Но всё равно остаются проблемы:
- background работает на всех страницах
- неактивная иконка различается на сайтах, где меняется через setIcon, и на странице расширения, где оно действительно недоступно
- в списке разрешений запрашивается выполнение "На всех сайтах", которые пользователь конечно может ограничить вручную, но например в "Google Документы оффлайн" доступ запрашивается только к двум конкретным ссылкам.
Как можно схавать текст в элементе сверху, в параграфе?
Я написал и это работает, но что-то кажется, что кривовато как-то вышло?
HTML
.item
p Lorem ipsum dolor sit amet
button.jsBtn Press me
JS
const btns = document.querySelectorAll(".jsBtn");
if (btns.length > 0) {
btns.forEach((btn) => {
btn.addEventListener("click", function () {
showModal(this);
});
});
}
function showModal(el) {
let text = el.closest('.item').querySelector('p').innerText;
console.log(text);
}
вопрос знатокам, есть проект на vue3, использую для отображения таблиц vue-good-table, надо добавить кнопки в каждую строчку в колонку actions, для выполнения edit/delete реквестов на бэк. что я делаю не так?
<template>
<div class="col">
<div class="pagination">
<button @click="fetchPreviousPage" :disabled="currentPage === 1">Previous</button>
<button @click="fetchNextPage" :disabled="!hasNextPage">Next</button>
</div>
<vue-good-table
:columns="columns"
:rows="providers"
:paginate="true"
:globalSearch="true"
:search-options="{
enabled: true,
searchFn: searchFunc,
placeholder: 'Input your search text',
trigger: 'enter'
}"
:lineNumbers="false"
@on-page-change="handlePageChange"
>
<template slot="table-actions" slot-scope="props">
<button @click="editProvider(props.row)">✏️</button>
<button @click="deleteProvider(props.row.id)">🗑</button>
</template>
</vue-good-table>
<div class="pagination">
<button @click="fetchPreviousPage" :disabled="currentPage === 1">Previous</button>
<button @click="fetchNextPage" :disabled="!hasNextPage">Next</button>
</div>
</div>
</template>
<script>
import {VueGoodTable} from 'vue-good-table-next';
import axios from 'axios';
import 'vue-good-table-next/dist/vue-good-table-next.css';
export default {
components: {
VueGoodTable
},
data() {
return {
providers: [],
columns: [
{label: 'Provider Name', field: 'providerName'},
{label: 'Telematic Name', field: 'telematicName'},
{label: 'Access', field: 'access'},
{label: 'Tracker location', field: 'gpsTrackerLocation'},
// {label: 'Credentials', field: 'parameters', sortable: false},
// ... other columns ...
{label: 'Actions', field: 'actions', sortable: false, globalSearchDisabled: true}
],
currentPage: 1
};
},
methods: {
fetchProviders(page) {
axios.get(http://example.com/providers?page=${page}
)
.then(response => {
if (response.data.length === 0) {
this.hasNextPage = false;
} else {
this.providers = response.data;
this.hasNextPage = true;
}
})
.catch(error => console.error(error));
},
searchFunc(row, col, cellValue, searchTerm) {
if (searchTerm.length > 0) {
axios.get(http://example.com/providers/?searchQuery=${searchTerm}
)
.then(response => {
this.providers = response.data;
})
.catch(error => console.error(error));
return this.providers;
} else {
this.fetchProviders(1)
}
},
fetchNextPage() {
if (this.hasNextPage) {
this.currentPage += 1;
this.fetchProviders(this.currentPage);
}
},
fetchPreviousPage() {
if (this.currentPage > 1) {
this.currentPage -= 1;
this.fetchProviders(this.currentPage);
}
}
},
created() {
this.fetchProviders(this.currentPage);
}
};
</script>
поставить в проект через
npm install htmlparser2
а они не исключитеьно нодовские, я лично использовал htmlparser2 и в ноде, и в браузере
Читать полностью…Не разбираюсь как нодрвскую библиотеку в браузере использовать. Если я правильно понимаю, то там надо как минимум код адаптировать под браузер, ибо браузер не умеет то, что умеет нода
Читать полностью…А вообще я не понимаю как люди парсят html в service worker. Или ни у кого такой задачи никогда не встает. Я так понимаю вообще никто не может парсить html готовыми решениями, потому что библиотек нет, и функционал воркера так не умеет, что звучит очень тупо в рабочей среде БРАУЗЕРА! При том на гитхабе самого проекта service worker уже 2 года идет большой дискус с разработчиками дать какой-нибудь аналог DOMParser или что-то для парсинга без привязки к дом конечно, по типу beautiful soup, а разрабы будто один год не понимают что их спрашиваю,рассказывая про ограничения воркера, отвечают не вдаваясь в суть вопроса, потом 2 год поняли что от них хотят и стали предлагать миллион странных вариантов, типа на какой-нибудь странице создать фрэйм и там парсить данные. А смысл тогда в сервис воркере, если придется идти в браузер и забирать работу скриптов пользователя. С таким успехом можно и манифестом 2 обойтись.. Принудительно на манифест 3 с воркерами пересаживают, а нужного функционала не дают. Видимо поэтому все мои расширения пишут на манифесте 2
Читать полностью…Тогда лучше использовать beautiful soup а не расширение, это быстрее и удобнее, чем плагин. Плагин больше заточен для работы с api браузера
Читать полностью…Как раз gpt4 предложил такое решение 😁 Думал, есть более правильный способ. Если нет, ничего страшного, спасибо за внимание. В целом, вопрос показался мне достаточно интересным для обсуждения
Читать полностью…Не совсем: сейчас у меня через background в chrome.tabs.onUpdated делается chrome.action.disable и chrome.action.setIcon, если url не совпадает
Читать полностью…Сейчас так и делаю. Думал может более опытные коллеги решали эту задачу менее костыльным способом. Если есть пример, кажется что должно быть и решение. Может я чего-то не понимаю в ограничениях хрома.
Читать полностью…Хмм.. Немного не понятно, но порядок действий ясен. Спасибо. Попробую. Хотя кажется, что на регулярках было бы проще😄
Читать полностью…Хмм.. Так а как его можно заюзать, не подскажешь? Я просто не сталкивался с подобным. Просто, во первых в гите в src всë на typescript, во вторых, там нету js файлов и папок с названием "htmlparser2", чтобы импортировать объект уже у себя
Читать полностью…И как заюзать его в браузере? На стаковерфлоу находил ответ, что хтмлпарсер2 онли нод
Читать полностью…Никогда не писал расширения, но в чём проблема подключить какуюнть либу, которая не зависит от DOM’а? типа htmlparser2 или parse5
Читать полностью…Так я пишу расширение не для парсинга на Питоне😂 зачем такие сложности) мне нужен парсер по функционалу и легковесности как beautiful soup. Я находил парсеры, но они все имеют слишком мощный функционал вплоть до полной "эмуляции" DOM, много весят и использую кучу библиотек. Поэтому хотелось бы аналог чего-то простого по типу супа. При том все парсеры написаны для node, а я не особо разбираюсь на сколько ноды совместимы с браузерами, как их под браузер собрать да и возможно ли. скорее всего да, но думаю нужны будут костыли. Слишком геморно для обычной задачи спарсить html
Читать полностью…Если вы писали на манифесте3, то подскажите как я могу парсить html? Мне DOM не нужен. Мне нужен парсер по типу BeautifulSoup на Питоне
Читать полностью…