چو چشمت

قرار نیست که همیشه درمورد کامپیوتر بنویسیم، گاهی باید شعر خوند.
سلمان ساوجی یکی از شاعر‌هایی هست که کمتر شناخته شده ولی شعرهای بسیار خوبی داره و واقعا این شعرش لایق تمجیده

چو چشمت هرگزم چشمی به چشمم در نمی‌آید
به چشمانت که چشمم را به جز چشمت نمی‌باید

چو چشمت چشم آن دارد که ریزد خون چشم من
اگر چشمت به چشمانم زند چشمی بیاساید

هر آن چشمی که می‌بیند به غیر چشم او چشمی
چو چشمش چشم تو بیند ز چشمش چشمه بگشاید

به سوی چشم من چشمی، بکن ای نور چشم من
که تا چشمم ز چشمانت به چشمانی بیاساید

به وعده چشم تو گفته: که چشمم را به چشم آرد
به چشمت هم شتابی کن که چشمم چشم می‌باید

چه دانی حال چشم من چو چشمت نیست در چشمم؟
که چشمم در غم چشمت چه خون از چشم پالاید

اگر چشمت به چشم آرد به چشم خویش سلمان را
خوشا چشمی که پیش چشم تو جانا به چشم آید

امکان انتقال برنامه به کارت حافظه در اندروید

چندباری میشه که کاربران سال در نظرات درخواست کردند که امکان انتقال برنامه به حافظه خارجی ایجاد بشه، این ویژگی از اندروید 2.2 (API 8) ایجاد شده و برنامه‌ها می‌تونند به کارت حافظه خارجی انتقال پیدا کنن، ولی این کار بصورت پیش‌فرض قابل انجام نیست و برنامه‌ها باید تنظبمات خاصی داشته باشند تا بتونند به حافظه خارجی منتقل بشند. البته منظور از تنظیمات چیز پیچیده‌ای نیست، به گفته مستندات اندروید فقط کافبه این خطر رو به <manifest> برنامه اضافه کنیم. android:installLocation="preferExternal"
به گفته مستندات اندروید installLocation میتونه دو حالت داشته باشه، یکی preferExternal، توی این حالت اولویت نصب با حافظه خارجی است و در وجود خطا در نصب روی حافظه خارجی (برای مثال عدم وجود فضای خالی) در حافظه داخلی نصب می‌شود. حالت دیگر هم auto است که هیچ ترجیحی در نصب را اعمال نمی‌کند.
دقت داشته باشید که تنها در صورتی که installLocation در <manifest> وجود داشته باشد برنامه می‌تواند در حافظه خارجی ذخیره شود.‌


1
2
3
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >

SearchView in Android Toolbar

قریب به ۹۰٪ برنامه‌های اندروید برای خودشون تولبار دارند، تولبار نقش مهممی در کاربر نرم‌افزار داره، دکمه Back مهمترین اکشنی‌است که در تولبار استفاده میشه و من شخصا در خیلی مواقع بجای دکمه فیزیکی گوشی از اون استفاده می‌کنم. اکشن مهم دیگه‌ای هم که در تولبار وجود داره، امکان جست‌جو هست، همین نواری که توی تولبار باز میشه و امکان تایپ متن مورد نظر رو به ما میده.


Toolbar

درست کردن این نوار کار چندان سختی نیست. در فایل xml منو خودتون آیتم زیر رو اضافه کنید.


1
2
3
4
5
6
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"/>

درون اکتیویتی خودتون، موقعی که آپشن-منو ساخته میشه، تنظیمات رو انجام بدید


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.dashboard, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = null;
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
}
return super.onCreateOptionsMenu(menu);
}

اکتیویتی جدید برای دریافت اکشتن جست‌جو بسازید


1
2
3
4
5
6
7
<activity android:name=".activity.SearchResultActivity" android:label="@string/title_activity_search_result" android:launchMode="singleTop" android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
</activity>

فایل xmlای به نام searchable.xml درون فولدر xml برنامه خود بسازید و کد زیر را در آن بنویسید


1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search_hint"
android:label="@string/app_name" />

حال تنها کافی‌است درون اکتیویتی SearchResultActivity عبارت سرچ شده را از بگیرید و نتایج جست‌جو را نمایش دهید.


1
2
3
4
5
String query;
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}

اتصال به درگاه بانک در اندروید بدون دردسر

چند وقت پیش آرش مطلبی در مورد حل مشکل WebView در اندروید نسخه چهار نوشته بود، مشکل این بود که چون certificate سایت‌های بانکی معتبر نبود، webview اونهارو باز نمی‌کرد. این به خودی خود باگ محصوب نمیشه ولی خب تو بستر فعلی اینترنت ما باگ هستش. از اندروید ۵ به بعد مشکل دیگری هم وجود داره، و اون اینکه چه با روشی که آرش گفته و چه بدون اون، webview نمی‌تونه داده‌ای از یک صفحه https به یک صفحه http ارسال کنه، چون جلوی اینکار گرفته شده. و تو اندروید پنج Mix Content Mode بصورت پیش‌فرض غیرفعال شده.
برای اینکه بتونیم بدون مشکل هر کار ناشایستی که خواستیم با WebView بکنیم، باید مقدار MixedContentMode را به MIXED_CONTENT_ALWAYS_ALLOW تغییر دهیم.

1
2
3
4
WebSettings settings= webView.getSettings();
if (Build.VERSION.SDK_INT >= 21) {
settings.setMixedContentMode( WebSettings.MIXED_CONTENT_ALWAYS_ALLOW );
}

ساخت ویجت(View) اختصاصی در اندروید

اگر می‌خواید یک ویجت یکپارچه و تروتمیز بسازید که جاهای مختلف ازش استفاده کنید، بهترین راه ساختن یک ویجت اختصاصی برای خودتونه، چیزی که بتونید بدون کپی پیست کردن کدهای قبلی و تنها با با فراخوانی و تعریف اون براحتی ازش استفاده کنید. مثلا در مورد خود من، من می‌خواستم ویجتی داشته باشم که هم نقش دکمه رو برای من ایفا بکنه و هم اینکه یک لودینگ برای من باشه، به همین منظور اومدم و یک کلاس (ویجت) اختصاصی برای خودم ساختم و هرجا نیاز داشتم از این ویجت استفاده کرده و دیگه خبری از کپی پیست نبود.
اول ببینیم ویجتی که من می‌خواستم داشته باشم چه‌شکلی بود؟


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">
<RelativeLayout
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_centerInParent="true"
android:text="@string/action_sign_in"
android:id="@+id/lbtext_title" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lbimage_icon"
android:src="@drawable/ic_done_white_24dp"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/lbtext_title"
android:layout_toLeftOf="@+id/lbtext_title" />
<android.support.v4.widget.ContentLoadingProgressBar
android:id="@+id/lbloading_indicator"
style="?android:attr/progressBarStyle"
android:background="@color/btn_green"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:layout_gravity="center_horizontal"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
</RelativeLayout>

همونطور که می‌بینید این ویجت یگ آیکون، یک متن و یک پراگرس‌بار داره که قراره نقش یک دکمه رو عمل بکنه و در مواقع نیاز به شکل یک لودینگ در بیاد. گام بعدی برای ایجاد ویجت خودمون ساختن یک کلاس و لود کردم این layout درون اونه.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package ir.farnabaz;
public class LoaderButton extends RelativeLayout implements View.OnClickListener {
TextView textView;
ImageView actionIcon;
ContentLoadingProgressBar progress;
OnClickListener clickListener;
public LoaderButton(Context context) {
super(context);
init(null);
}
public LoaderButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public LoaderButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
public LoaderButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
public void setText(String text) {
textView.setText(text);
}
public void setLoading(boolean loading) {
if (loading) {
progress.setVisibility(VISIBLE);
} else {
progress.setVisibility(GONE);
}
}
public void setIcon(Drawable icon) {
actionIcon.setImageDrawable(icon);
}
public boolean isLoading() {
return progress.getVisibility() == VISIBLE;
}
@Override
public void setOnClickListener(OnClickListener l) {
this.clickListener = l;
}
@Override
public void onClick(View view) {
if (!isLoading() && clickListener != null) {
clickListener.onClick(view);
}
}
private void init(AttributeSet attrs) {
inflate(getContext(), R.layout.layout_loader_button, this);
textView = (TextView) findViewById(R.id.lbtext_title);
actionIcon = (ImageView) findViewById(R.id.lbimageView);
progress = (ContentLoadingProgressBar) findViewById(R.id.lbloading_indicator);
super.setOnClickListener(this);
}
}

مهمترین بخش این کلاس تابع init هست که فایل xml مارو لود میکنه و می‌کنه و قراره تنظیمات لازم رو هم انجام بده برای ما. بقیه توابع هم بسته به نیاز ساخته شده‌اند تا بشه راحت با ویجت کار کرد، مثلا setIcon برای اینکه بشه آیکون دکمه رو عوض کنیم.
تا همینجا هم کار تمومه و ما الان یک ویجت برای خودمون داریم، کافیِ تو فایل دیزاین خودمون از اون استفاده کنیم


1
2
3
4
5
6
7
8
<ir.farnabaz.LoaderButton
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/btn_green"
android:layout_alignParentBottom="true"
android:id="@+id/btn_submit"
android:layout_alignParentLeft="true">
</ir.farnabaz.LoaderButton>

ولی اگه بخوایم توی فایل xml دیزاین خودمون متن یا آیکون دکمه رو عوض کنیم داستان چجوری میشه؟ خب این کار تو اندروید کمی مسخره است، یعنی از دید من مسخره است، چون باید اول تعریف کنیم که ویجت ما میتونه ویژگی‌های خاصی داشته باشه و بعد توی کلاس خودمون اون ویژگی‌ها (همون آیکون و متن دکمه) رو بخونیم و استفاده کنیم.
برای تعریف ویژگی‌ها فایلی به نام attrs.xml توی فولدر values بسازید و کد زیر رو درونش قرار بدید.


1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LoaderButton">
<attr name="android:text"/>
<attr name="android:icon"/>
</declare-styleable>
</resources>

فایل بالا مشخص میکنه که ویجت ما میتونه دوتا ویژگی android:text و android:icon رو داشته باشه. جالا برگردیم سراغ کلاس خودمون و توی تابع init این تیکه کد رو اضافه کنیم تا همه چی به خیر و خوشی تموم بشه :)


1
2
3
4
5
6
7
8
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(
attrs,
R.styleable.LoaderButton);
textView.setText(a.getString(R.styleable.LoaderButton_android_text));
actionIcon.setImageDrawable(a.getDrawable(R.styleable.LoaderButton_android_icon));
}

آش کشک اندرویدی

طی پروژه اخیر چیزای زیادی بوده که برای پیدا کردن راه‌حل اونها توی اندروید مجبور شدم سرچ کنم و از آدمای دیگه جوابم رو بگیرم، اینجا میخوام بعضی‌هاشون رو توی پست بریزم و آش کشک اندرویدی درست کنم براتون :)

ارسال درخواست به سرور با متود‌های PUT و POST و …


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void doRequest(String url, String method, String data) {
URL url = new URL(url);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod(method);
if (data != null) {
OutputStreamWriter out = new OutputStreamWriter(
httpCon.getOutputStream());
out.write(data);
out.close();
}
httpCon.getInputStream();
// TODO
}
doRequest("http://site.com", "PUT", "DATA");
doRequest("http://site.com", "POST", "DATA");

راست‌چین کردن چک‌باکس و قرار دادن تیک در سمت راست


1
2
3
4
5
6
7
8
9
10
<! --
android:button="@null"
android:drawableRight="?android:attr/listChoiceIndicatorMultiple"
-->
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:text="hello"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:button="@null"
android:drawableRight="?android:attr/listChoiceIndicatorMultiple"/>

دکمه‌های بدون حاشیه(Border) در متریال دیزاین


1
2
3
4
5
6
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DONE"
style="?android:attr/borderlessButtonStyle"
/>

تعیین اندازه سایز متن یک TextView درون کد جاوا با متریک DP


1
2
3
desiredSp = getResources().getDimension(R.dimen.desired_sp);
density = getResources().getDisplayMetrics().density;
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, desiredSp / density);

ایجاد پدینگ‌هایی که منجر بخشی از محتوای View باشند، همانند پدینگ‌های وب


1
2
3
4
5
6
7
8
9
10
<! --
android:clipToPadding="false"
-->
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:paddingTop="8dp"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />

ایجاد انیمیشن دایره‌ای مختص متریال دیزاین هنگام تاچ یک View


1
2
3
4
<View
...
android:background="?android:attr/selectableItemBackground"
/>

درنهایت هم چند تا مطلب درمورد متریال دیزاین توی اندروید

ابرگراف‌ها

همه ما با گراف‌ها کمابیش آشناییم، حتی اگر آشنا هم نباشم ساختار‌هایی که گراف نامیده می‌شوند رو دیدیم و شاید اسمشونو نمیدونیم، برای مثال تصویر زیر رو نگاه کنید. گراف زوج مرتبی از دو مجموعه‌ بنام راس‌ها(vertex) و یال‌ها(edge) هست، بطوری که هر یال معادل اتصال میان دو راس هست توی شکل زیر {0, 1, 2} مجموعه راس‌ها و {a, b} مجموعه یال‌ها هستند. هر یال نشان‌دهنده اتصال دو راس است. این تعریفی بود که اکثر ما از گراف‌ها توی ذهن خودمون داریم.
گراف


یک گراف از مجموعه‌ای غیر خالی از اشیاء به نام رأس تشکیل شده، که آن را با V نشان می‌دهیم، و مجموعه‌ای شامل یال‌ها، که رأس‌ها را به هم وصل می‌کنند و با E نمایش می‌دهیم. یک چنین گرافی را با G = (V,E)نشان می‌دهیم. اگر یال y دو رأس v1 و v2 را به هم وصل کند می‌نویسیم y = { v1,v2 }
ویکیپدیا

قراره اینجا مفهوم جدیدی رو باهم ببینیم به اسم ابرگراف‌ها یا hypergraph. برخلاف گراف‌های عادی که در اونها هر یال فقط دو راس رو بهم وصل میکنه، توی ابرگراف‌ها هر یال با به بیان بهتر هر ابریال(hyperedge) میتونه چند (تعداد دلخواه) راس رو به هم وصل بکنه، شکل زیر نشون دهنده یک ابرگراف است. (هر ابریال میتونه یک، دو، سه و یا بیشتر تعداد راس رو به هم متصل بکنه.)
alt=”ابرگراف” />
حال فرض کنید که ابرگرافی‌هایی وجود دارند که هر ابریالشون فقط میتونه دو راس رو به هم وصل بکنه، این ابرگراف‌ها همون گراف‌های دوست داشتنی خودمون هستند. یعنی گراف یک حالت خاص از ابرگراف محسوب میشه!
برای نمایش ابرگراف‌ها از ماتریس تداخل استفاده میشه به این صورت که سطر‌ها مشخص کننده راس‌ها و ستون‌ها مشخص کننده ابریال‌های ابرگراف هستند، هر درایه aij از ماتریس برابر یک هست اگر راس i در ابریال j وجود داشته باشه.
برای مثال اگر مجموعه راس‌ها برابر {a, b, c} و مجموعه ابریال‌ها برابر {‌{a}, {a,b}, {a,c}, {a, b, c}} باشه، گراف متناظر این ابر گراف به شکل زیر خواهد بود.

A=(100110101111)


ابرگراف‌ها چیز جدایی از گراف‌هایی که ما دیدیم نیستند، مفاهیمی که برای گراف‌ها داشتیم اینجا هم وجود داره، مفاهیمی مثل همبندی، دوبخشی‌بودن، k-colorable، منتظم بودن و …
اینجا چند تا از مفاهیم رو باهم میبینیم:


  • k-uniform: اگر تمامی ابریال‌های یک ابرگراف دقیقا k راس را به من متصل کنند، ابرگراف رو k-uniform میگیم

  • k-regular: اگر تمامی راس‌های یک ابرگراف دقیقا در k ابریال حضور داشته باشند اون ابرگراف رو k-regular میگیم.

  • Bipartite: ابرگرافی رو دوبخشی می‌نامیم که بتونیم راس‌های اون رو طوری از در دو گروه قرار بدیم که هر یال حداق یک راس از هر گروه رو درون خودش داشته باشه.

  • Dual: اگر جای راس‌ها و ابریال‌های یک ابرگراف رو عوض کنی ابرگراف حاصل رو دوگان ابرگراف نخست می‌نامند.

    اگر به تعریف k-uniform و k-regular رو در نظر بگیریم متوجه میشیم که دوگان هر ابرگراف k-uniform یک ابرگراف k-regular خواهد بود و بر عکس.





* برای خود من مفهوم و ساختار ابرگراف‌ها جالب بودند برای همین خواستم معرفی کوتاه و جمع‌و‌جوری توی بلاگ ازشون بنویسم، اگر خواستید درمورد ابرگراف‌ها بیشتر بدونید میتونید به منابعی که در زیر نوشتم سری بزنید.

ویرایش چند اشاره‌گرِ در IntelliJ

شرکت JetBrains خالق IDE های بزرگی مثل PHP Storm, pyCharm و IntelliJ، من شخصا طرفدار این برنامه‌ها نیستم ولی خب پدر کشتگی‌ای باهاشون هم ندارم، در مواقع نیاز ازشون استفاده میکنم. چیزی که توی IDEها من دوست ندارم کند بودن اونها نسبت به ویرایش‌گرهای متن مثل سابلیم و اتم است و البته نداشتن برخی از امکانات این ویرایش‌گرها که من عاشق اون‌ها هستم، یکی از این امکانات ویرایش چند اشاره‌گره است، این ویژگی درسته که اولین بار توسط سابلیم اختراع و استفاده نشده ولی بدلیل اینکه بوسیله این ویرایشگر اینقدر مشهور شد و مورد استفاده قرار گرفت اصطلاحا Sublime Text Style Multiple Selections نامیده میشه.(تصویر نمونه زیر نحوه کار این ویژگی رو نمایش میده)




Sublime Text Style Multiple Selection


سال پیش شرکت جت‌برین هم این ویژگی رو به IntelliJ اضافه کرد که خب باعث میشه من یک امتیاز مثبت برای IntelliJ توی ذهنم در نظر بگیرم :) میانبر‌های استفاده از این ویژگی هرچند به راحتی میانبرهای سابلیم و اتم نیستند ولی چندان فضایی همی نیستند.


  • ایجاد و حذف یک اشاره‌گر:‌Alt + Shift + کلیک

  • انتخاب و عدم انتخاب تکرار بعدی کلمه انتخاب شده: Alt + J / Shift + Alt + J (Ctrl + G / Shift + Ctrl + G) for Mac OS X)

  • انتخاب تمامی تکرارهای یک عبارت/کلمه: Shift + Ctrl + Alt + J (Ctrl + Cmd + G for Mac OS X)

  • برای حذف اشاره‌گرها هم تنها کافی‌است کلید Esc را فشار دهید.


PDO::FETCH_KEY_PAIR|PDO::FETCH_GROUP

من وقتی چیزی رو یاد میگیرم خیلی کم میرم دنبال راه‌کار برای مسائلی که میتونم دستی حل کنم ولی خب تو مسیر خیلی پیش میاد که راه‌حل‌های موجود به چشمم بخوره،چیزی که الان میخوام بگم در مورد PDO از جمله این راه‌حل‌هاست که به چشمم خورد و گفتم شاید جالب باشه که بنویسمش.
فرض کنید جدولی داریم که دو ستون داره، ستون اول شناسه و ستون دوم نام (مثلا نام کشور) و میخوایم این جدول رو بخونیم و بصورت key-value در بیاریم، خب من همیشه از جدول میخوندم و با یک حلقه این کار رو میکردم، ولی امروز چیزی به چشمم خورد با نمک بود، با خود کتابخونه PDO میشه این کار رو انجام داد بدون نیاز به یک خط کد تنها کافیه موقع fetch دو تا وضعیت به تابع بفرستیم. این دوتا PDO::FETCH_KEY_PAIR|PDO::FETCH_GROUP

1
2
3
$pdo->prepare($query)
->execute($params)
->fetchAll(PDO::FETCH_KEY_PAIR|PDO::FETCH_GROUP);
1
2
3
4
5
6
7
8
9
# table
+-----+-------+
| mid | title |
+-----+-------+
| 1 | Iran |
| 4 | China |
+-----+-------+
# result
{1:"Iran",4:"China"}

حذف افزونه‌های ناخواسته از فایرفاکس

خیلی وقت پیش مطلبی نوشته بودم برای بازگردونی صفحه پیش‌فرض تب‌های جدید توی فایرفاکس که الان تبدیل شده به پربازدیدترین پست بلاگ من. در همین مطلب یکی از دوستان پرسیده بوده که چجوری افزونه‌های ناخواسته رو حذف کنم؟
من هم تصمیم گرفتم بجای کامنت زیر اون پست، جواب رو توی یک پست جدا بدم.


اگر دنبال این هستید که افزونه‌های فایرفاکس خودتون رو حذف کنید، اول باید به بخش افزونه‌های فایرفاکس بریم، برای اینکار از منوی Tools گزینه Add-ons رو انتخاب کنید، یا توی نوار آدرس فایرفاکس عبارت about:addons رو تایپ کنید.
Firefox addons
در صفحه ظاهر شده در بخش Extensions تمامی افزونه‌های فعال یا غیر فعال مرورگر رو میبینید، خیلی راحت روی دکمه Remove هر افزونه‌ای که نیازش ندارید کلید کنید، پس از اون هم فایرفاکس رو ببندید و دوباره باز کنید.

به امید روزی که هیچ مزاحمی برای کار شخصی شما وجود نداشته باشه