مطالب
آموزش فایرباگ - #10 - DOM Panel
در پنل DOM توابع و متغییرهایی که در صفحه وجود دارند بصورت درختی نمایش داده می‌شوند. object‌ها و array‌ها قابل باز شدن هستند و بصورت درختی می‌توانید محتویات آن‌ها را مشاهده کنید. توابع هم بصورت لینک هستند که با کلیک برون آن ها، کد مربوط در پنل Script نمایش داده می‌شود. توجه کنید که محتویاتی که مشاهده می‌کنید برای همان لحظه ای است که پنل را باز کردید و برای مشاهده تغییرات ثانویه باید محتویات پنل را بروزرسانی کرد.

قبل از بررسی این پنل اجازه دهید نگاهی به تعریف DOM بیندازیم.

DOM چیست؟
مدل شیءگرای سند یا دام (DOM - Document Object Model) عنوان یکی از دو ساختوارۀ (architecture) اصلی است (در کنار اس‌اِی‌اکس) که بر اساس آن سندهای اکس‌ام‌ال را به اشیایی که در بردارندهٔ آن است، تجزیه نموده، و آن‌ها را به‌صورت یک ساختار درختی داده‌ها در فضای حافظه اصلی پهن می‌کند. ساختوارۀ دام، نه به زبان برنامه‌نویسی خاصّی وابستگی دارد و نه به سکّوی برنامه‌نویسی ویژه‌ای، بلکه، به منظور اجراء و پیاده‌سازی آن باید از یک زبان برنامه‌نویسی بلندتراز همچون جاوا، سی‌شارپ، جاوااسکریپت یا مشابه آن‌ها سود بجوییم. آنسوی رابط کاربر سند با مدلی شیءگرا نمایانده می‌شود. 


Options Menu
این منو با راست کلیک کردن بروی نام پنل یا کلیک کردن بروی مثلثی که روی پنل قرار دارد، نمایش داده می‌شود.

  • Show User-defined Properties
    در صورت فعال بودن، پراپرتی هایی که توسط کاربر به صفحه اضافه شده اند را نمایش می‌دهد.
  • Show User-defined Functions
    در صورت فعال بودن، توابعی که توسط کاربر به صفحه اضافه شده اند را نمایش می‌دهد.
  • Show DOM Properties
    در صورت فعال بودن، پراپرتی هایی که بصورت پیشفرض در DOM وجود دارند را نمایش می‌دهد.
  • Show DOM Functions
     در صورت فعال بودن، توابعی که بصورت پیشفرض در DOM وجود دارند را نمایش می‌دهد.
  • Show DOM Constants
    در صورت فعال بودن، const هایی که بصورت پیشفرض در DOM وجود دارند را نمایش می‌دهد.
  •  Show Inline Event Handlers
    در صورت فعال بودن، رویدادهایی که بصورت خطی در تگ‌ها تعریف شده اند را نمایش می‌دهد.
  • Show Closures
    در صورت فعال بودن، Closure‌ها را نمایش می‌دهد.
  • Show Own Properties Only
    در صورت فعال بودن، فقط پراپرتی هایی که بروی خود شئ تعریف شده اند را نمایش می‌دهد.
  • Show Enumerable Properties Only
    در صورت فعال بودن، فقط پراپرتی‌های شمارشی را نمایش می‌دهد.
  • Refresh
    محتویات پنل را بروزرسانی می‌کند.


Property Path
این قسمت در بالاترین بخش پنل قرار دارد و وظیفه‌ی آن نمایش مسیر شئ از خود شئ تا window است.
همچنین با راست کلیک کردن بروی این قسمت دو گزینه نمایش داده می‌شود. Refresh برای بروزسازی آدرس نمایش داده شده و Use in Command Line هم برای استفاده از شئ در خط فرمان است. پس از راست کلیک کردن بروی یک شئ و انتخاب گزینه‌ی Use in Command Line فایرباگ تمرکز برنامه را به خط فرمان منتقل می‌کند و شئ را تحت متغییری به نام $p در خط فرمان کپی می‌کند.


رنگ ها
برای مشخص کردن نوع متغییرهای این پنل، فایرباگ برای هر نوع متغییر از یک رنگ استفاده می‌کند.
اشیاء
، اشیاء DOM ، توابع Getter ، توابع تعریفی کاربر ، توابع DOM ، توابع Constructor ، پراپرتی‌های Read-only 


Auto-Completion
مشابه پنل‌های Console, CSS, HTML در این پنل هم امکان اعمال تغییرات همراه با قابلیت تکمیل خودکار وجود دارد.


localStorage
در HTML5 سیستمی برای ذخیره مقادیر در سمت کاربر، به نام localStorage معرفی شد. در این پنل می‌توانید محتویات آن را بررسی/ویرایش کنید. برای کار با توابع آن هم می‌توانید از پنل Console استفاده کنید. ( همچنین می‌توانید از پنل Console بصورت Popup در این پنل و پنل‌های دیگر هم استفاده کنید. به تصویر زیر توجه فرمایید. )
توجه کنید که برای مشاهده‌ی این شئ، باید گزینه‌ی Show DOM Properties فعال باشد و همیچنین در Property Path، شئ window فعال باشد.

Breakpoint Column
شما می‌توانید با کلیک بروی ستون سمت چپ پراپرتی ها، آن پراپرتی را تحت نظر گرفته و در صورت تغییر یافتن مقدار آن پراپرتی، کنترل روند اجرای برنامه از همان نقطه را بدست بگیرید. به این صورت که زمانی که کدی پراپرتی موردنظر را تغییر دهد، پنل Script روند اجرای کد را در همان قسمت متوقف می‌کند.
( ممکن است فایرباگ بصورت خودکار به پنل Script سوئیچ نکند و بعد از متوقف شدن برنامه هم اگر به پنل Script سوئیچ کنید نتیجه را نبینید. پس بهتر است قبل از تغییر یافتن پراپرتی مورد نظر و بعد از قرار دادن Breakpoint به پنل Script بروید. )


Context Menu
با راست کلیک کردن در قسمت‌های مختلف پنل، منوهای متفاوتی را خواهید دید. همچنین با راست کلیک کردن بروی مقادیر پراپرتی ها، منوی متناسب با آن مقدار را خواهید دید. مثلا اگر بروی یک تگ HTML در این پنل راست کلیک کنید، منویی که خواهید دید همان منویی است که در پنل HTML مشاهده می‌کردید.

 گزینه Context
توضیحات
Copy Name
Property List نام پراپرتی را در حافظه کپی می‌کند.
Copy Path Property List آدرس پراپرتی را در حافظه کپی می‌کند.
Copy Value
String and Number values محتوای پراپرتی را در حافظه کپی می‌کند.
Edit Property... Property List ( پراپرتی و توابع کاربر )
پراپرتی را به حالت ویرایش می‌آورد.
Delete Property Property List ( پراپرتی و توابع کاربر ) پراپرتی را حذف می‌کند.
Break On Property Change Property List ( پراپرتی و توابع کاربر ) مشابه پاراگرف قبلی.
Refresh Property List, Property Path محتویات پنل را بروزرسانی می‌کند.

برای توابع هم دو منوی اضافی وجود دارد:

    • ‪ Log Calls to "<function name>"
      فراخوانی‌های تابع مورد نظر را Log می‌کند. ( برای توضیحات بیشتر دستور monitor که از توابع خط فرمان است را ملاحظه بفرمایید. )
    • Copy Function
      نام و بنده‌ی تابع را در حافظه کپی می‌کند.
مطالب
آموزش TypeScript #1
با گسترش روز افزون زبان برنامه نویسی Javascript و استفاده هر چه بیشتر آن در تولید برنامه‌های تحت وب این زبان به یکی از قدرت‌های بزرگ در تولید برنامه‌های مبتنی بر وب تبدیل شده است. ترکیب این زبان با Css و Html5 تقریبا هر گونه نیاز برای تهیه و توسعه برنامه‌های وب را حل کرده است. جاوا اسکریپت در ابتدا برای اسکریپت نویسی سمت کلاینت برای صفحات وب ایجاد شد و برای سال‌ها به‌عنوان ابزاری برای مدیریت کردن رویدادهای صفحات وب محدود شده بود  و در نتیجه بسیاری از امکانات لازم برای برنامه‌نویسی برنامه‌های مقیاس بزرگ را به‌همراه نداشت. امروزه به قدری Javascript  توسعه داده شده است که حتی در تولید برنامه‌های Native مانند Windows Store  و برنامه‌های تحت Cloud نیز استفاده می‌شود. پیشرفت‌های صورت گرفته و اشاره شده در این حوزه موجب شد تا شاهد پیداش برنامه‌های مبتنی بر جاوا اسکریپت با سایزهای بی سابقه‌ای باشیم و این بیانگر این بود که تولید برنامه‌های مبتنی بر جاوا اسکریپت در مقیاس‌های بزرگ امر دشواری است و اینک TypeScript توسط غول نرم افزاری جهان پا به عرصه گذاشته که این فرآیند را آسان‌تر نماید. به کمک TypeScript می‌توان برنامه تحت JavaScript در مقیاس بزرگ تولید کرد به طوری با هر مرورگر و سیستم عاملی سازگار باشد. TypeScript از شی گرایی نیز پشتیبانی می‌کند و خروجی آن در نهایت به JavaScript کامپایل می‌شود. خیلی‌ها عقیده دارند که هدف اصلی مایکروسافت از تولید و توسعه این زبان رقابت با CoffeeScript است.  CoffeeScript یک زبان متن باز است که در سال 2009 توسط Jeremy Ashkenas ایجاد شده است و سورس آن در GitHub موجود می‌باشد. در آینده، بیشتر به مباحث مربوط به CoffeeScript و آموزش آن خواهم پرداخت.

در تصویر ذیل یک مقایسه کوتاه بین CoffeeScript و TypeScript را مشاهده می‌کنید.

با TypeScript چه چیزهایی به دست خواهیم آورد؟

یک نکته مهم این است که این زبان به خوبی در Visual Studio پشتیبانی می‌شود و قابلیت Intellisense نوشتن برنامه به این زبان را دلپذیرتر خواهد کرد و از طرفی دیگر به نظر من یکی از مهم‌ترین مزیت هایی که TypeScript در اختیار ما قرار می‌دهد این است که می‌توانیم به صورت Syntax آشنای شی گرایی کد نویسی کنیم و خیلی راحت‌تر کد‌های خود را سازمان دهی کرده و از نوشتن کد‌های تکراری اجتناب کنیم.

یکی دیگر از مزیت‌های مهم این زبان این است که این زبان از Static Typing به خوبی پشتیبانی می‌کند. این بدین معنی است که شما ابتدا باید متغیر‌ها را تعریف کرده و نوع آن‌ها را مشخص نمایید و هم چنین در هنگام پاس دادن مقادیر به پارامتر‌های توابع باید حتما به نوع داده ای آن‌ها دقت داشته باشید چون کامپایلر بین انواع داده ای در TypeScript تمایز قایل است و در صورت رعایت نکردن این مورد شما با خطا مواجه خواهید شد. این تمایز قایل شدن باعث می‌شود که برنامه هایی خواناتر داشته باشیم از طرفی باعث می‌شود که خطا یابی و نوشتن تست برای برنامه راحت‌تر و تمیزتر باشد. بر خلاف JavaScript، در TypeScript(به دلیل پشتیبانی از شی گرایی) می‌توانیم علاوه بر داشتن کلاس، اینترفیس نیز داشته باشیم و در حال حاضر مزایای استفاده از اینترفیس بر کسی پوشیده نیست.

به دلیل اینکه کد‌های TypeScript ابتدا کامپایل شده و بعد تبدیل به کد‌های JavaScript می‌شوند در نتیجه قبل از رسیدن به مرحله اجرای پروژه، ما از خطاهای موجود در کد خود مطلع خواهیم شد.

البته این نکته را نیز فراموش نخواهیم کرد که این زبان تازه متولد شده است(سال 2012 توسط Anders Hejlsberg) و همچنان در حال توسعه است و این در حال حاضر مهم‌ترین عیب این زبان می‌تواند باشد چون هنوز به پختگی سایر زبان‌های اسکریپتی در نیامده است.

در ذیل یک مثال کوچک به زبان TypeScript و JavaScript را برای مقایسه در خوانایی و راحتی کد نویسی قرار دادم:

TypeScript:

class Greeter {
    greeting: string;

    constructor (message: string) {
        this.greeting = message;
    }

    greet() {
        return "Hello, " + this.greeting;
    }
}
بعد از کامپایل کد بالا به کدی معادل زیر در JavaScript تبدیل خواهد شد:
var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
توضیح چند واژه در TypeScript

Program : یک برنامه TypeScript مجموعه ای از یک یا چند Source File است. این Source File‌ها شامل کد‌های پیاده سازی برنامه هستند ولی در خیلی موارد برای خوانایی بیشتر برنامه می‌توان فقط تعاریف را در این فایل‌های سورس قرار داد.
Module: ماژول در TypeScript شبیه به مفاهیم فضای نام یا namespace در دات نت است و می‌تواند شامل چندین کلاس یا اینترفیس باشد.
Class : مشابه به مفاهیم کلاس در دات نت است و دقیقا همان مفهوم را دارد. یک کلاس می‌تواند شامل چندین تابع و متغیر با سطوح دسترسی متفاوت باشد. در TypeScript مجاز به استفاده از کلمات کلیدی public و private نیز می‌باشید. یک کلاس در Typescript می‌تواند یک کلاس دیگر را توسعه دهد(ارث بری در دات نت) و چندین اینترفیس را پیاده سازی نماید.
Interface: یک اینترفیس فقط شامل تعاریف است و پیاده سازی در آن انجام نخواهد گرفت. یک اینترفیس می‌تواند چندین اینترفیس دیگر را توسعه دهد.
Function: معادل متد در دات نت است. می‌تواند پارامتر ورودی داشته باشد و در صورت نیاز یک مقدار را برگشت دهد.
Scope: دقیقا تمام مفاهیم مربوط به محدوده فضای نام و کلاس و متد در دات نت در این جا نیز صادق است. 


آماده سازی Visual Studio برای شروع به کار
در ابتدا باید Template مربوطه به TypeScript را نصب کنید تا از طریف VS.Net بتوانیم به راحتی به این زبان کد نویسی کنیم. می‌توانید فایل نصب را از اینجا دانلود کنید. بعد از نصب از قسمت Template‌های موجود گزینه Html Application With TypeScript را انتخاب کنید

یا از قسمت Add  در پروژه‌های وب خود نظیر MVC گزینه TypeScript File را انتخاب نمایید.


در پست بعدی کد نویسی با این زبان را آغاز خواهیم کرد. 

نظرات مطالب
تصادفی کردن آیتمهای لیست با استفاده از Extension Method
یک نکته‌ی تکمیلی

تا دات نت 7 می‌توان از روش زیر برای انتخاب تصادفی اعضای یک مجموعه استفاده کرد:
‍MyCollection.OrderBy(x => Random.Shared.Next()).Take(10)
Random.Shared، به دات نت 6 برای تولید اعداد تصادفی thread-safe اضافه شد. اهمیت thread-safe بودن آن‌را در مطلب «اثبات قانون مشاهده‌گر در برنامه نویسی» می‌توانید مطالعه کنید.
مطالب
نمایش HTML در برنامه‌های Angular
فرض کنید قصد داریم خاصیت htmlContent زیر را در قالب این کامپوننت نمایش دهیم:
export class ShowHtmlComponent {
  htmlContent = "Template <script>alert(\"Hello!\")</script> <b>Syntax</b>";
}
اگر از روش متداول binding استفاده شود:
<h3>Binding innerHTML</h3>
<p>Bound value:</p>
<p>{{htmlContent}}</p>
چنین خروجی حاصل خواهد شد:


همچنین اگر به کنسول developer tools مرورگر مراجعه کنیم، چنین اخطاری نیز درج شده است:
 WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
به این معنا که Angular به صورت توکار تمام خروجی‌ها را به صورت encode شده نمایش می‌دهد و در مقابل حملات XSS مقاوم است. Sanitizing نیز در اینجا به معنای تغییر ورودی و تبدیل آن به مقداری است که جهت درج در DOM امن است.


روش نمایش HTML در برنامه‌های Angular

اما اگر خواستیم اطلاعات HTML ایی را به همان صورتی که هستند نمایش دهیم چطور؟ در این حالت باید از روش ویژه‌ی ذیل استفاده کرد:
<p>Result of binding to innerHTML:</p>
<p [innerHTML]="htmlContent"></p>
برای نمایش HTML نیاز است آن‌را به ویژگی innerHTML متصل کرد؛ با این خروجی:


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

روش دیگر کار با innerHTML، تعریف یک template reference variable در قالب کامپوننت است:
<p #dataContainer></p>
و سپس دسترسی به آن از طریق یک ViewChild و انتساب مقداری بهinnerHTML  آن به صورت ذیل:
export class ShowHtmlComponent implements OnInit {

  @ViewChild("dataContainer") dataContainer: ElementRef;

  ngOnInit() {
    this.dataContainer.nativeElement.innerHTML = "nativeElement <script>alert(\"Hello!\")</script> <b>Syntax</b>";
  }
}
با این خروجی:


که اینبار قسمت script آن به طور کامل حذف شده‌است.


حالات مختلفی که Angular برنامه را از حملات XSS محافظت می‌کند

در ذیل، لیست مواردی را مشاهده می‌کنید که به صورت پیش‌فرض توسط Angular در مقابل حملات XSS محافظت می‌شوند و اطلاعات انتساب داده شده‌ی به آن‌ها تمیزسازی خواهند شد:
HTML 
Attributes – 
<div [innerHTML]="UNTRUSTED"></div> 
OR <input value="UNTRUSTED">

Style— 
<div [style]="height:UNTRUSTED"></div>

URL — 
<a [href]="UNTRUSTED-URL"></a> 
OR <script [src]="UNTRUSTED-URL"></script> 
OR <iframe src="UNTRUSTED-URL" />

GET Parameter – 
<a href="/user?id=UNTRUSTED">link</a>

JavaScript Variable –
<script> var value='UNTRUSTED';</script>


تبدیل کردن یک HTML نا امن ورودی به یک HTML امن در Angular

بهتر است اطلاعات دریافتی از کاربران پیش از ارسال به سرور تمیز شوند. برای این منظور می‌توان از سرویس ویژه‌ای به نام DomSanitizer کمک گرفت. کار این سرویس، امن سازی اطلاعات نمایش داده شده‌ی در برنامه‌های Angular است.
export class ShowHtmlComponent implements OnInit {
  sanitizedHtml: string;

  constructor(private sanitizer: DomSanitizer) { }

  ngOnInit() {
    this.sanitizedHtml = this.sanitizer.sanitize(SecurityContext.HTML, "<b>Sanitize</b><script>attackerCode()</script>");
  }
}
در این حالت سرویس DomSanitizer به سازنده‌ی کلاس تزریق شده و سپس می‌توان از متدهای مختلف آن مانند sanitize استفاده کرد. خروجی آن صرفا حذف تگ اسکریپت و نگهداری کدهای درون آن است.


در این حالت می‌توان موارد ذیل را کنترل کرد. برای مثال اگر مقدار دریافتی CSS است، می‌توان از SecurityContext.STYLE استفاده کرد و سایر حالات آن مانند امن سازی HTML، اسکریپت و آدرس‌های اینترنتی به شرح ذیل هستند:
SecurityContext.NONE
SecurityContext.HTML
SecurityContext.STYLE
SecurityContext.SCRIPT
SecurityContext.URL
SecurityContext.RESOURCE_URL


غیرفعال کردن سیستم امنیتی Angular جهت نمایش کامل یک مقدار HTML ایی

اگر خواستیم اطلاعات HTML ایی را با فرض امن بودن آن، به همان نحوی که هست نمایش دهیم چطور؟
سرویس DomSanitizer شامل متدهای ذیل نیز می‌باشد:
export enum SecurityContext { NONE, HTML, STYLE, SCRIPT, URL, RESOURCE_URL }

export abstract class DomSanitizer implements Sanitizer {
  abstract sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
  abstract bypassSecurityTrustHtml(value: string): SafeHtml;
  abstract bypassSecurityTrustStyle(value: string): SafeStyle;
  abstract bypassSecurityTrustScript(value: string): SafeScript;
  abstract bypassSecurityTrustUrl(value: string): SafeUrl;
  abstract bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl;
}
اولین متد آن sanitize است که در مورد آن توضیح داده شد. سایر متدها، کار غیرفعال سازی سیستم امنیتی توکار Angular را انجام می‌دهند.
برای کار با آن‌ها همانند مثال استفاده‌ی از متد sanitize می‌توان سرویس DomSanitizer را به سازنده‌ی یک کامپوننت تزریق کرد و یا می‌توان این عملیات تکراری فرمت اطلاعات ورودی را تبدیل به یک Pipe جدید کرد:
import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl } from "@angular/platform-browser";

@Pipe({
  name: "safe"
})
export class SafePipe implements PipeTransform {
  constructor(protected sanitizer: DomSanitizer) { }

  public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
    switch (type) {
      case "html":
        return this.sanitizer.bypassSecurityTrustHtml(value);
      case "style":
        return this.sanitizer.bypassSecurityTrustStyle(value);
      case "script":
        return this.sanitizer.bypassSecurityTrustScript(value);
      case "url":
        return this.sanitizer.bypassSecurityTrustUrl(value);
      case "resourceUrl":
        return this.sanitizer.bypassSecurityTrustResourceUrl(value);
      default:
        throw new Error(`Invalid safe type specified: ${type}`);
    }
  }
}
کار این Pipe غیرفعال کردن سیستم امنیتی Angular و نمایش html، style و غیره به همان صورتی که هستند، می‌باشد.
برای استفاده‌ی از آن، ابتدا این Pipe به قسمت declarations ماژول مدنظر اضافه خواهد شد:
@NgModule({
  imports: [
  // ...
  ],
  declarations: [ SafePipe]
})
و سپس در قالب کامپوننت به نحو ذیل می‌توان با آن کار کرد:
<p [innerHTML]="htmlContent | safe: 'html'"></p>
در این حالت متد bypassSecurityTrustHtml بر روی htmlContent، فراخوانی شده و نتیجه‌ی نهایی نمایش داده خواهد شد.


کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید.
اشتراک‌ها
پایتون و VSCode

«...اگر برنامه نویس پایتون باشید حتما محیط Pycharm را بهترین و راحت‌ترین گزینه برنامه نویسی با این زبان می‌دانید. اما در چند سال اخیر حضور قدرتمند Visual Code را نمی‌توانید نادیده بگیرید...» 

پایتون و VSCode