سالها میگذرد؛ حادثهها میآید؛ انتظار فرج از نیمهی آبان کشم…
شاید شما به JQuery نیاز نداشته باشید!
طراحان وب اغلب با کتابخانهی JQuery آشنا هستند؛ این کتابخانه با آماده کردن دستوراتی بسیار کوتاه در زبان جاوا اسکریپت، به طراحان وب کمک میکند تا بدون نیاز به نوشتن دستورات پیچیده، وبسایتهای پویا و غیر ثابت طراحی کنند.
این کتابخانه سالهای نسبتا زیادی است که در حال توسعه و ارائه نسخههای جدید است اما با توسعهی استانداردهای برنامهنویسی وب و زبان جاوااسکریپت و همچنین سنگین شدن کتابخانهی JQuery، این روزها استفاده از این کتابخانه به خصوص در وبسایتهای حساس به سرعت و حجم توجیه چندانی ندارد و توسعهدهندگان میتوانند از دستورات و قابلیتهای بروز جاوا اسکریپت برای رفع نیازهای خود استفاده کنند.
در همین زمینه وبسایت You Might Not Need jQuery با ارائهی جایگزینهای بومی هر دستور جیکوئری در زمینههای مختلف (AJAX، افکتها و…)، به توسعهدهندگان کمک میکند تا وبسایت خود را سبکتر طراحی کنند.
بروزرسانی: این وبسایت به زبان فارسیست و محتوای مشابهی با وبسایتی که قبلا معرفی کردهام دارد:
مَثَل امام…
مَثلُ الْامامِ مَثَلُ الْکعْبَةِ، اذ تُوْتی وَ لَا تَأْتِی…
استفاده از رایانهی دیگر در شبکه برای پردازش نرمافزار (معرفی و کار با RemoteApp)
یکی از چالشهای موجود در آمادهسازی فضای کاری چند نفره، انتخاب قطعات رایانه با توجه به نیاز کاربران و هزینهی تمامشدهی هر یک است. ممکن است در ابتدا قطعاتی برای رایانه انتخاب شود اما در ادامهی فعالیت، پاسخگوی نیاز نبوده و مجبور شوید تا با صرف زمان و هزینه، قطعهی ضعیف را با قطعهی قویتری جابجا کنید؛ اما چقدر خوب خواهد بود اگر کاربران از طریق شبکه به یک رایانهی بزرگ متصل شوند و طبق نیازشان از آن استفاده کنند؟ خوشبختانه این قابلیت تحت عنوان RemoteApp در ویندوز وجود دارد.
RemoteApp چیست؟
RemoteApp اولینبار توسط مایکروسافت و در ویندوزهای Windows 7 و Windows Server 2008 R2 معرفی شد. این قابلیت بر مبنای RDP یا همان پروتکل ریموت دسکتاپ معروف ویندوز طراحی شده و به کاربران یک شبکه این امکان را میدهد تا به جای اتصال به دستگاه دیگر و نمایش تمامصفحه، یک نرمافزار را در آن دستگاه باز کرده و پنجرهی آن را مانند یک نرمافزار محلی در دستگاه خود ببیند و با آن کار کند.
نرمافزارهایی که به کمک قابلیت RemoteApp اجرا میشوند، تجربهای کاملا محلی ارائه داده و در صورتی که سرعت اتصال شبکهی خوبی داشته باشید بسیار روان عمل میکنند. نکتهی جالب دیگر اینکه طبق آزمایش ما روی ویندوز سرور، میتوان از چند دستگاه با یک حساب کاربری یکسان به سرور متصل شده و نرمافزار را اجرا کرد؛ در حالی که Remote Desktop عادی اجازهی فعالیت همزمان یک کاربر روی چند کلاینت را نمیدهد.
راهاندازی RemoteApp برای نرمافزارها
در صورتی که از ویندوز سرور در یک فضای کاری استفاده میکنید، میتوانید طبق آموزش موجود در وبسایت مایکروسافت شروع به کار کنید؛ برای این کار میبایستی ابتدا یک سرور RD Web Access را راهاندازی کرده باشید.
روش سادهتر، استفاده از RemoteApp Tool
طبق جستجوهایی که داشتم، با استفاده از تعدادی کلید رجیستری و تعریف یک میانبر RDP خاص، میتوان امکان اجرای یک نرمافزار از طریق RemoteApp را بدون پیچیدگی و ایجاد زیرساخت خاص فعال کرد. خوشبختانه یکی از کاربران گیتهاب ابزار مناسبی برای انجام این کارها به صورت خودکار را طراحی کرده است که از اینجا قابل دریافت است.
روند کاری بسیار ساده است؛ ابتدا با زدن دکمهی «+» یک نرمافزار را وارد لیست کنید و سپس با زدن دکمهی «Create Client Connection» یک میانبر RDP ایجاد کنید. با اجرای میانبر در رایانههای هدف، نام کاربر در رایانهی اصلی پرسیده شده و چندبار هشدار امنیتی داده میشود (که چیز مهمی نیست). در نهایت کمی منتظر بمانید تا نرمافزار اجرا شود…
نکتهی جالب اینکه در این نرمافزارها، هم درایوهای سرور و هم کلاینت (به صورت Map Drive شده) در لیست درایوها مشاهده میشوند.
ویندوز قابلیت جالب دیگری به نام MultiPoint دارد؛ یادم باشد که آن را هم بررسی کنم…
تبدیل پیامهای ماژول سیمکارت به متن عادی با جاوا اسکریپت
در قسمت ۱۸+۱ از مجموعه آموزشی آردوینو با محوریت اینترنت اشیاء یاد گرفتیم که پیامها در استاندارد GSM (مانند پیامک و پاسخهای کدهای دستوری USSD) به صورت پیشفرض با رمزگذاری ASCII هفت بیتی رد و بدل میشوند. در صورتی که از حروف دیگری در پیامها استفاده شود، میبایستی به وسیله دستورات AT مربوطه، وضعیت کدپیج را روی حالت دیگری تنظیم کرد تا پیام به درستی منتقل شود.
مناسبترین کدپیج ماژولهای سیمکارت در حال حاضر برای حروف یونیکد، UCS-2 است. UCS-2 در واقع همان UTF-16 است که (مثل اوایل ایجاد UTF-16) به صورت ۲ بایتی ثابت، ۶۵,۵۳۶ حرف ابتدایی جدول یونیکد را پوشش میدهد.
ماژولهای سیمکارت پیامهای یونیکدی را به صورت Hex میگیرد و ارسال میکند؛ یعنی مثلا «0645» به جای «م» در جدول یونیکد.
در پروژهای نیاز بود تا میزان شارژ از طریق USSD گرفته شده و (از آنجایی که هر اپراتور متن تصادفی خودش را نشان میدهد 😑) متن پاسخ در صفحه وب به کاربر نمایش داده شود. تابع زیر که به زبان جاوا اسکریپت نوشته شده، ورودی Hex را به متن عادی تبدیل میکند:
1 2 3 4 5 6 7 8 9 10 |
function decodeUCS2String(str) { let decoded = "", strLen = str.length; if (strLen % 4 != 0) { throw new Error("Unexpected byte string length"); } for (let i = 0; i < strLen; i+=4) { decoded += String.fromCodePoint("0x"+str[i]+str[i+1]+str[i+2]+str[i+3]); } return decoded; } |
نکته مهم در این تبدیل این است که محتوای هگزی که ماژولهای سیمکارت بر میگردانند به صورت غیر Byte-Swap است (بایت سواپ یعنی بایتها جابجا هستند؛ یعنی اگر هر حرف ۲ بایت باشد، ابتدا بایت دومی و سپس بایت اولی قرار میگیرد). مثلا در تبدیل متن زیر:
064506270646062F0647002006270639062A0628062706310020062F06310020063306270639062A003A002006F006F9003A06F406F2000D000A06F106F006F006F006F006F00020063106CC062706440020000D000A06F1002D062E063106CC062F00200634062706310698000D000A000D000A06F906F9002D06280627063206AF0634062A
در صورتی که رمزگشایی به صورت Byte-swap باشد تبدیل خراب خواهد شد:
‘䔆✆䘆⼆䜆 ✆㤆⨆⠆✆ㄆ ⼆ㄆ ㌆✆㤆⨆㨀 句㨀ഀ ㄆ찆✆䐆 ഀⴀ⸆ㄆ찆⼆ 㐆✆ㄆ順ഀഀ句句ⴀ⠆✆㈆꼆㐆⨆’
در حالی که حالت غیر Byte-Swap به صورت صحیح رمزگشایی میشود:
مانده اعتبار در ساعت: ۰۹:۴۲
۱۰۰۰۰۰ ریال
۱-خرید شارژ
۹۹-بازگشت
یک ترفند: اگر نمیدانید ماژول سیمکارت پیام را به صورت ASCII میفرستد یا یونیکد، باقیمانده تقسیم تعداد حروف پیام بر ۴ را بگیرید؛ اگر ضریب ۴ بود احتمال قوی یونیکد است و اگر نبود ۱۰۰٪ یونیکد نیست!
تبدیل JSON به XLS در جاوا اسکریپت
با استفاده از این تابع میتوان ورودی JSON با عمق 2 شئ داخلی را به یک پرونده XLS (همان TAB Separated Values) تبدیل و دانلود کرد:
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 |
function jsonToXls(JsonObject) { if (!JsonObject) return; // Construct csv var csv = []; Object.entries(JsonObject).forEach(([paramKey, paramValue]) => { csv.push(paramKey); var keys = []; var values = []; Object.entries(paramValue).forEach(([key, value]) => { keys.push(key); values.push(value); }); csv.push(keys.join('\t')); csv.push(values.join('\t')); csv.push(''); }); var csv_string = csv.join('\n'); var filename = (new Date().toLocaleDateString('fa-IR', { month: '2-digit', day: '2-digit', year: 'numeric' })).replace(/[۰-۹]/g, d => '۰۱۲۳۴۵۶۷۸۹'.indexOf(d)) + '_json.xls'; var link = document.createElement('a'); link.style.display = 'none'; link.setAttribute('target', '_blank'); link.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string)); link.setAttribute('download', filename); document.body.appendChild(link); link.click(); document.body.removeChild(link); } |
برای صابر راستیکردار…
دیشب مشغول کار روی موتور بودم و گوشی کنارم بود. صدای اعلان آمد و برداشتم؛ دیدم سروش+ اعلان تبلیغاتی داده که «به حمایت از خالق هنرمند فونت وزیر، صابر…»، اعلان را حذف کردم.
چند لحظه فکر کردم، «حمایت»؟ «فونت وزیر»؟ «صابر»؟ سروش+ را باز کردم، پیام این بود:
«میخوان از صابر راستیکردار حمایت کنن؟ چطور؟ چرا الان؟». چشمهای خستهام بین کلمات دنبال جواب میگشت: «هزینههای درمانی؟ اون که سن و سالی نداره!»؛
لینک مطلب را خواندم. راستش، چی بگم، شُکرهای بعد از شرح ماوقع بیشتر دلم را آتیش زد…
صابر راستیکردار را از سال ۹۵ شناختم. زمستان آن سال وسط درگیریهای کنکور میخواستم دوباره وبسایتی برای خودم بسازم تا مطالب و نمونهکارهایم را منتشر کنم. دنبال قالب رایگان و زیبا برای وردپرس میگشتم که قالب فعلی سایت را پیدا کردم:
همیار وردپرس آن را در نسخههای فونت وزیر، یکان و عربیک کوفی منتشر کرده بود و من که برای اولینبار نام فونت وزیر را میشنیدم با شک آن را نصب کردم و نه تنها تا امروز جایگزینی برای این قالب با این فونت پیدا نکردم بلکه فونتهای وزیر و شبنم تبدیل به اصلیترین فونتهای کار من شدند…
امیدوارم که خود صابر این مطلب را هیچوقت نخواند؛
از وقتی مطلب وبلاگش را میخواندم، فکر میکردم که شاید روزی همدیگر را ببینیم، با هم صحبت کنیم، از باطن افراد خبر ندارم اما چون در مطالبش دغدغههای خودم را دیدم فکر میکردم شاید با هم پروژهای را شروع کنیم، روی او به عنوان یک توسعهدهنده که گرفتار آفت روشنفکری مدرن این روزها نشده و یک پایه برای دنیای نرمافزارهای آزاد حساب باز کرده بودم؛ فکر است دیگر…
حالا راستش من از او ناامیدترم؛ نمیدونم…
پ.ن: شاید الان بهترین موقع برای حمایت مالی از صابر راستیکردار به خاطر پروژههای رایگانش باشه، شاید هم آخرین موقع…
دریافت درایورهای تبدیل سریال به USB (CH340G و CP210x)
در صورتی که از مبدلهای TTL به USB استفاده میکنید ممکن است به صورت پیشفرض توسط ویندوز شناسایی نشوند؛ در این صورت میتوانید آخرین نسخههای آن را از لینکهای زیر دریافت کنید:
چطور با جاوا اسکریپت، یک svg را به صورت png دانلود کنیم؟
در یکی از پروژهها نیاز بود تا کاربر بتواند یک تصویر svg را به صورت png دانلود کند (! نیازه دیگه چه میشه کرد!😁)؛ با مقداری تحقیق و بررسی و ترکیب تعدادی کد با یکدیگر به این کد رسیدم:
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 |
function downloadVectorAsPng(vectorName) { var mySvg = document.getElementById(vectorName); var myCanvas = document.createElement('canvas'); myCanvas.style = "display: none;"; myCanvas.width = mySvg.clientWidth*5; myCanvas.height = mySvg.clientHeight*5; document.body.appendChild(myCanvas); var ctx = myCanvas.getContext('2d'); var svgData = (new XMLSerializer()).serializeToString(mySvg); var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); var svgBlob = new Blob([svgData], {type: 'image/svg+xml;charset=utf-8'}); var url = DOMURL.createObjectURL(svgBlob); img.onload = function () { ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, myCanvas.width, myCanvas.height); ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); var imgURI = myCanvas .toDataURL('image/png') .replace('image/png', 'image/octet-stream'); var evt = new MouseEvent('click', { view: window, bubbles: false, cancelable: true }); var a = document.createElement('a'); a.setAttribute('download', 'VectorDiagram_' + new Date().toLocaleDateString() + '.png'); a.setAttribute('href', imgURI); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); }; img.src = url; } |
روش کار کد به صورت خلاصه این است که ابتدا svg در یک متغیر ذخیره شده و سپس یک canvas نامرئی ساخته میشود؛ در ادامه تصویر svg درون canvas رسم شده و در نهایت با ترفندِ ساخت لینک مخفی و کلیک مصنوعی، تصویر برای کاربر دریافت میشود.
- ابعاد canvas بر مبنای ابعاد svg تنظیم میشود. برای اینکه تصویر زیادی کوچک نباشد، عرض و ارتفاع تصویر در 5 ضرب شده است که میتوانید آن را تغییر دهید.
- برای اینکه پسزمینه تصویر نهایی نامرئی نباشد، ابتدا یک مستطیل سفید در ابعاد کل canvas رسم شده (
ctx.fillRect) و سپس تصویر svg رسم میشود.
نان و نمک
امروز مشغول کار بودیم که زنگ در رو زدن؛ یک جوانی با دو کارتن بزرگ بستنی پریما در دست وارد شد و بعد از تبریک نیمه شعبان به ما بستنی تعارف کرد. وقتی رفت فهمیدیم که از بچههای تیم ایتا بود.
شیرینیِ پیامرسان داخلی نخورده بودیم که توفیق شد. حیف شد، تازه میخواستم برایشان شمشیر از رو بکشم و نقد کنم 😂.