Расширение Chrome: запускайте Content Script перед запуском любых встроенных скриптов на странице

Я пытаюсь изменить поведение проигрывателя YouTube, изменив некоторые переменные внутри скрипта player_api, встроенного в html-страницу просмотра видео.

Встроенный скрипт, который я пытаюсь изменить

Проблема в том, что что бы я ни пытался, встроенный скрипт плеера всегда запускается до того, как мое расширение добавит к нему модификации. Таким образом, поведение игрока остается прежним.

Я попытался установить для свойства run_at в своем манифесте значение document-start, но тогда скрипт не запустился вообще.

Что я могу сделать, чтобы остановить выполнение этого скрипта, пока я не внесу в него изменения?

PS: я попытался изменить скрипт, перехватив вызов html и отредактировав тело с помощью Charles Proxy, и поведение игрока изменилось, как я хотел. Так что он знает, что это должно сработать, если сделать это в нужное время.

.

manifest.json

{
    "manifest_version": 2,
    "name": "YouFit For YouTube",
    "version": "1",
    "content_scripts": [{
        "js": ["content.js"],
        "matches": ["https://*.youtube.com/watch?*",
        "https://*.youtube.com/watch?*"],
    }],
    "browser_action": {
        "default_icon": "icon.png"
    }
}

content.js

function changeBehavior() {
    var scriptElements = document.getElementsByTagName('script');
    for (var i = 14; i < scriptElements.length; i++) {
        var curScriptBody = scriptElements[i].outerHTML;
        // Find the script i'm interested in
        if (curScriptBody.indexOf("var ytplayer") != -1) {
            scriptElements[i].outerHTML = scriptElements[i].outerHTML.replace("<text>", "<replacement text>");
            alert("Replaced");
            break;
        }
    }
}
changeBehavior();

person DarkMental    schedule 14.02.2018    source источник
comment
Замена html элемента сценария ничего не дает, потому что это происходит после выполнения сценария, и в Chrome нет возможности сделать это заранее. Это не сработает так. Вам придется отменить URL скрипта до того, как он загрузится, загрузить его содержимое самостоятельно, изменить его, вставить как новый элемент скрипта. Где-то должен быть такой пример, продолжайте искать.   -  person wOxxOm    schedule 15.02.2018
comment
Скрипт не загружается с URL. Его содержимое вводится внутри тега script. Это имеет значение?   -  person DarkMental    schedule 15.02.2018
comment
Затем вам нужно будет перезаписать всю страницу: 1) window.stop() 2) получить исходный html vix XHR/fetch 3) выполнить замену текста 4) перезаписать страницу через document.write()   -  person wOxxOm    schedule 15.02.2018
comment
Я потратил много времени, пытаясь следовать вашему предложению. Я не мог, хотя я все еще новичок в расширениях Chrome и сценариях контента. Я размещу вознаграждение в размере 50–100 баллов в течение 8 часов в надежде получить более наглядный ответ. Спасибо за предложение :)   -  person DarkMental    schedule 16.02.2018
comment
Что-то вроде этого скрипта.   -  person wOxxOm    schedule 16.02.2018
comment
Предоставьте дополнительную информацию, какой URL вы пытаетесь захватить, какую переменную изменить?   -  person Munim Munna    schedule 18.02.2018
comment
@MunimMunna Любой URL-адрес watch?id=videoID я хочу добавить тег в массив ключевых слов внутри скрипта, который будет растягивать видео, чтобы оно соответствовало экранам 16x9. Я добавляю тег, просто заменяя keywords: на keywords:yt:stretch=16:9,   -  person DarkMental    schedule 19.02.2018
comment
Пожалуйста, укажите цель, которую вы хотите достичь, а не решение, которое вы пробовали. (meta.stackexchange.com/questions/66377/ что такое xy-проблема) Вы не можете достичь того, чего хотите (изменить встроенный скрипт) без хакерских хаков (как предложено wOxxOm), но ваша реальная проблема, вероятно, решаема с менее хакерскими хаками.   -  person haldagan    schedule 21.02.2018
comment
@haldagan Я в порядке с хаками. Цель, которую я хочу достичь, - отредактировать встроенный скрипт до того, как он запустится.   -  person DarkMental    schedule 21.02.2018
comment
На самом деле, (если я правильно понял) ваша цель состоит в том, чтобы изменить поведение некоторых игроков по умолчанию, а не изменять встроенный скрипт. Однако при изменении встроенных скриптов: вы можете попробовать покопаться в webRequest (developer.chrome.com/extensions/webRequest), чтобы узнать, поможет ли это перехватить и изменить текущий запрос страницы, но я не совсем уверен, что это вам поможет). UPD: Нет, кажется, вы не можете изменить ответ.   -  person haldagan    schedule 21.02.2018
comment
@haldagan Попробовав предложение wOxxOm в другой раз. На самом деле это помогло изменить скрипт перед его запуском, однако я не могу найти способ преобразовать html из XHTTP.responseText в документ, затем выполнить замену целевого встроенного скрипта, а затем преобразовать его обратно в html-текст. что я могу ввести, используя document.write Похоже, что замена регулярного выражения на весь текст html не дает никакого результата.   -  person DarkMental    schedule 21.02.2018
comment
Я на самом деле не знаю, в чем была проблема, но если вы настаиваете на том, что document.write не выполняет свою работу, то (погружаясь все глубже и глубже в hax) вы всегда можете попробовать вставить iframe на страницу с src равным data-uri в кодировке base64, эквивалент всей полученной вами страницы. Тем не менее (как я полагаю) реальная проблема где-то рядом с командой window.stop. Я думаю, тебе стоило попробовать просто стереть body вместо этого.   -  person haldagan    schedule 21.02.2018
comment
@wOxxOm Награда заканчивается, и ваш ответ самый близкий, не могли бы вы поместить его в качестве ответа, чтобы я наградил вас баллами за награду?   -  person DarkMental    schedule 23.02.2018


Ответы (1)


Вы пробовали что-то подобное?

контент.js

var script = document.createElement('script');
script.textContent = "/* What you have in content.js right now */";
(document.head||document.documentElement).prepend(script);
person Chris Cinelli    schedule 23.02.2018
comment
Запустив это в document_start, похоже, у меня пока нет доступа к другим элементам скрипта в этот момент. Запуск его в document_idle не приводит к замене на достаточно раннем этапе. - person DarkMental; 23.02.2018
comment
Такой недооцененный ответ. С run_at:document_start это решение запускает код в контексте страницы непосредственно перед выполнением любого скрипта и перед загрузкой любого элемента DOM. Именно то, что мне нужно. - person Andrew; 08.08.2019
comment
Я искал это весь день! Отличный ответ спасибо! - person xicocana; 07.06.2020