سؤال

أنا بصدد بناء أول امتداد لي في رحلة سفاري-وهو واحد بسيط للغاية-لكنني واجهت بعض المشكلات. يتلخص التمديد إلى نص واحد محقن يحاول تجاوز معالج التغذية الأصلي ويعيد التوجيه إلى http: // uri. مشكلاتي حتى الآن ذات شقين:

  1. "القائمة البيضاء" لا تعمل بالطريقة التي أتوقعها. نظرًا لأن جميع الأعلاف تظهر تحت بروتوكول "التغذية: //" ، فقد حاولت التقاط ذلك في القائمة البيضاء كـ "Feed: //*/*" (مع عدم وجود شيء في القائمة السوداء) ، لكنني انتهى بي الأمر في طلب حلقة لا أستطيع أن أفهمها. إذا قمت بتعيين القائمة السوداء قيم "http: //*/*" و "https: //*/*"، كل شيء يعمل كما هو متوقع.
  2. لا يمكنني معرفة كيفية الوصول إلى إعداداتي من البرنامج النصي الذي تم حقنه. البرنامج النصي يخلق أ beforeload معالج الأحداث ، ولكن لا يمكنك الوصول إلى إعداداتي باستخدام safari.extension.settings المسار المشار إليه في الوثائق.

لم أجد أي شيء في وثائق Apple للإشارة إلى أن الإعدادات يجب ألا تكون متاحة من البرنامج النصي الخاص بي. نظرًا لأن الامتدادات هي ميزة جديدة ، فإن Google تعود إلى نتائج محدودة ذات صلة ومعظمها من الوثائق الرسمية.

ماذا ينقصني؟

تحديثلذلك آمل أن تكون الوثائق غير مكتملة لأنها سهلة على الحدود ، لكنني تعلمت قليلاً عن الإعدادات. اتضح أنه من نصوص الحقن ، SafariExtensionSettings الكائن غير متوفر. نصوص الحقن فقط يمكنها الوصول إلى SafariContentExtension كائن (وهو أمر غير مفيد على الإطلاق) ، لكنه مستعار بنفس الطريقة تمامًا (safari.extension.settings)-فكرة سيئة ، IMO. كما ذكر في وثائق السيناريو الحقن:

هام: عند استخدام Safari.Extension من داخل البرنامج النصي المحقن ، فأنت لا تتعامل مع فئة Safariextension. أنت تتعامل مع فئة SafaricontentExtension.

يجب عليك استخدام نظام المراسلة للتحدث إلى ملف HTML عالمي يحتوي على إمكانية الوصول إلى الإعدادات. إنه نوع من الحلقات ، لكن لدي رسالة يتم إرسالها إلى global.html الملف الذي يسترجع الإعدادات وسيقوم بإرسال رسالة إلى البرنامج النصي للحقن بمجرد معرفة كيفية القيام بذلك.

نظرًا لأنني أقوم بكل عملي قبل تحميل المستند ، فإن جميع الطرق التي وجدتها لإرسال رسالة الى الخلف اعتمد على كائن صفحة ليس لدي.

هل كانت مفيدة؟

المحلول 3

استغرق الأمر مني عدة أيام ، لكنني أعتقد أنني وجدت حلًا عمليًا باستخدام canLoad() طريقة المراسلة. يسترجع البرنامج النصي للحقن الإعدادات عن طريق استدعاء صفحة HTML العالمية مثل هذا:

settings = safari.self.tab.canLoad( event );

يقوم ملف HTML العالمي ، بدوره ، بإرجاع تلك الإعدادات على النحو التالي:

settings = {
  'setting1': safari.extension.settings.getItem( 'setting1' )
}

msgEvent.message = settings;

لا يزال الأمر أكثر "اختراقًا" أكثر مما أود. لا يمكنني ببساطة إعادة كائن الإعدادات نفسه ، لذلك يجب عليّ تجميع كائن جديد عن طريق استرداد كل إعداد يدويًا. ليست مثالية ، لكنها تبدو فعالة.

نصائح أخرى

مثل أي شخص آخر في هذه المرحلة ، ما زلت أتسلق منحنى التعلم ، لكن إليكم الطريقة التي تعاملت بها مع هذه المشكلة:

لدي امتداد بسيط مع عدم وجود كروم ونص واحد حقن (script.js). لغرض تحميل إعدادات ، أضفت صفحة عالمية بسيطة (proxy.html). عند حقن script.js ، يرسل getSettings رسالة إلى proxy.html. Proxy.html يستجيب مع أ setSettings الرسالة ، و script.js تواصل التهيئة.

الصفحة الأكثر فائدة التي وجدتها في المستندات حول هذا الموضوع هي الرسائل والوكلاء.

proxy.html:

<!doctype html>
<html lang="en">
<head>
  <script type="text/javascript">
    safari.application.addEventListener( "message", function( e ) {
      if( e.name === "getSettings" ) {
        e.target.page.dispatchMessage( "setSettings", {
          sort_keys: safari.extension.settings.getItem( "sort_keys" )
        } );
      }
    }, false );
  </script>
</head>
<body></body>
</html>

script.js:

( function() {
  var settings, init = function() {
    // do extension stuff
  };

  // listen for an incoming setSettings message
  safari.self.addEventListener( "message", function( e ) {
    if( e.name === "setSettings" ) {
      settings = e.message;
      init();
    }
  }, false );

  // ask proxy.html for settings
  safari.self.tab.dispatchMessage( "getSettings" );
}() )

تعديل: كما قلت في تحديث النشر الأولي الخاص بك ، لا يحتوي البرنامج النصي الذي تم حقنه على نفس النوع من الوصول الذي ستحصل عليه صفحة HTML العالمية. هذا هو الحل الخاص بي ، تخيل أنك تريد معرفة قيمة تعيين "Foo" في البرنامج النصي المحقن:

رمز النص المحقن:

function getMessage(msgEvent) {

    if (msgEvent.name == "settingValueIs")
        alert("Value for asked setting is: " + msgEvent.message);

}

safari.self.tab.dispatchMessage("getSettingValue", "foo"); // ask for value
safari.self.addEventListener("message", getMessage, false); // wait for reply

رمز HTML العالمي:

function respondToMessage(messageEvent) {

    if (messageEvent.name == "getSettingValue") {

           // getItem("foo");
        var value = safari.extension.settings.getItem(messageEvent.message);
        // return value of foo to injected script
           safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("settingValueIs", value);

    } 

}

safari.application.addEventListener("message",respondToMessage,false);

أتمنى أن يساعدك هذا !


المنشور الأولي: أواجه نفس المشكلة الثانية مثلك ، لا يمكنني الوصول إلى الإعدادات الخاصة بي (أو تأمين) من البرنامج النصي المحقن. في حالتي ، يتم تحميل البرنامج النصي بعد تحميل الصفحة ، ولكن حتى بهذه الطريقة لا يمكنني استخدامها safari.extension.settings.

الطريقة الوحيدة التي تعمل بها هي شريط أدوات/زر ، يمكن لـ HTML وراء هذا العنصر getItem و setItem كما هو متوقع.

استنتاجي هو أنه ، لسبب ما ، لا يمكن للنصوص المحقونة الوصول إلى الإعدادات (في الواقع ، يبدو أنها لا يمكنها الوصول إلى safari عنصر). خطأ أو ميزة مقصودة ، تركت لمعرفة ذلك.

واجه نفس المشكلة ، لكن الإجابة أسهل مما يمكنك تخيله: قم بتضمين البرنامج النصي في HTML العالمي.

<!DOCTYPE HTML>
<script type="text/javascript" src="cleanup.js"></script>
<script>
…
</script>

ثم يمكنك الوصول إلى الإعدادات كما هو موضح في الوثائق safari.extension.settings.myKey

يمكنك أيضًا زيادة التصويت على TRAVIS ، لأنني حصلت على الفكرة منصبه

//تعديل:
في الواقع أنا لا أعرف حقًا ما هو الخطأ. استدعاء الإعدادات كأمر الأول ، ولكن ليس في وقت لاحق. بالإضافة إلى ذلك ، يبدو أنه يفسد البرنامج النصي الكامل بعد 2. الحقن. بحاجة إلى التحقق إذا كان فقط في نصي (صعب؟).

// edit2:
الآن حصلت على العمل لاستعادة كائن الإعدادات عبر dispatchMessage()

في الخاص بك injected.js

function gotSettings(msgEvent) {
   if (msgEvent.name === "SETTINGS") {
      setts = msgEvent.message;
      alert(setts.mySetting1);
      // run the programm
   }
}

safari.self.addEventListener("message", gotSettings, false);
safari.self.tab.dispatchMessage("getSettings");

و في global.html

switch (event.name) {
case "getSettings":
   // send the settings data
   event.target.page.dispatchMessage("SETTINGS", safari.extension.settings);

يعتمد على هذه وثائق Apple

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top