🔥 gildas-lormeau / SingleFile - Web Extension for saving a faithful copy of a complete web p
GitHub热门项目 | Web Extension for saving a faithful copy of a complete web page in a single HTML file | Stars: 21,579 | 84 stars today | 语言: JavaScript
找到 658 篇相关文章
GitHub热门项目 | Web Extension for saving a faithful copy of a complete web page in a single HTML file | Stars: 21,579 | 84 stars today | 语言: JavaScript
GitHub热门项目 | User editable database for TV channels. | Stars: 1,432 | 11 stars today | 语言: JavaScript
GitHub热门项目 | More than 200 powerful ESLint rules | Stars: 5,045 | 3 stars today | 语言: JavaScript
GitHub热门项目 | A visual no-code/code-free web crawler/spider易采集:一个可视化浏览器自动化测试/数据采集/网页爬虫软件,可以无代码图形化的设计和执行爬虫任务。别名:ServiceWrapper面向Web应用的智能化服务封装系统。 | Stars: 44,072 | 20 stars today | 语言: JavaScript
GitHub热门项目 | Make changes to FMHY | Stars: 10,140 | 44 stars today | 语言: JavaScript
Hello Dev Community! 👋 It is officially Day 31 — stepping straight into my second month of documented full-stack engineering! Fresh off the 30-day milestone yesterday, I decided to keep the engineering momentum high by building a classic browser game: Rock, Paper, Scissors using HTML5, CSS3, and vanilla JavaScript. After mastering API integration yesterday, today was about refinement—handling dynamic score states, tracking user choices, and creating a clean automated opponent engine. 🛠️ The Core Logic Architecture To make the game interactive and clean, I divided the code structure into distinct logical components: 1. Capturing User Selection I assigned the choices (rock, paper, scissors) to clickable image/div nodes in the layout. Instead of writing repetitive lines, I used a forEach array loop to attach an addEventListener("click", ...) to each choice, pulling the user's explicit selection instantly via DOM attributes. 2. The Computer's Automated AI Brain Since a computer cannot pick words, I mapped out an array of strings: ["rock", "paper", "scissors"] . I then utilized JavaScript's math utility library to generate a randomized index number: javascript const genCompChoice = () => { const options = ["rock", "paper", "scissors"]; const randIdx = Math.floor(Math.random() * 3); return options[randIdx]; };
Ever started a new project and found yourself rebuilding the same modal, dropdown, toast notification, tabs, and switches for the 20th time? I got tired of that. So I built UltraHTML , a lightweight UI library that gives you modern components with simple HTML and JavaScript, no framework required. Getting Started Include the CSS and JS files: <link rel= "stylesheet" href= "dist/ultra.css" > <script src= "dist/ultra.js" ></script> Initialize UltraHTML: Ultra . init (); Done. Buttons UltraHTML includes two button styles out of the box: ultra-button — a clean, modern button. ultra-button-wave — adds a wave/ripple-style interaction effect. Basic button: <button class= "ultra-button" > Simple Button </button> Wave button: <button class= "ultra-button ultra-button-wave" > Wave Button </button> Buttons use UltraHTML's default green theme, but because they're standard HTML elements, you can easily customize them with CSS. For example, here's a red button that displays a popup message: <button onclick= "Ultra.popupmsg('Hello from UltraHTML!')" class= "ultra-button ultra-button-wave" style= "background-color: red" > Show Popup </button> You can create buttons that match your site's branding without learning a separate theming system: <button class= "ultra-button" style= "background-color: #3b82f6;" > Blue Button </button> <button class= "ultra-button ultra-button-wave" style= "background-color: #f59e0b;" > Orange Button </button> <button class= "ultra-button ultra-button-wave" style= "background-color: #ef4444;" > Red Button </button> UltraHTML handles the styling and interactions while still giving you full control over how your buttons look. Modal Example Need to display important information? <script> window . addEventListener ( " load " , () => { Ultra . init (); Ultra . modal ({ head : " Important " , text : " You need to reset your password " , buttonText : " Reset " , buttonAction : ( modal ) => { console . log ( " Going to reset page... " ); modal . remove (); } }); }
If you sell a desktop app on Gumroad, it hands every buyer a license key. But Gumroad stops there — checking that key inside your app is entirely up to you. Here's how to do it properly in Node/Electron, plus the three traps that catch almost everyone. We'll use gumroad-license-lite, a tiny, zero-dependency, MIT-licensed helper (you can npm install it or just copy its ~120 lines). Turn on license keys in Gumroad On your product, enable "Generate a unique license key per sale," then grab your product_id (in the product settings / API). Every buyer now gets a key on their receipt. Verify a key const { verifyGumroadLicense } = require('gumroad-license-lite'); const result = await verifyGumroadLicense({ productId: 'YOUR_PRODUCT_ID', licenseKey, }); if (result.valid) { unlockApp(result.email); } result.valid is true only if the key is real and the sale wasn't refunded, disputed, or a cancelled subscription — not just "does this key exist," which is gotcha #1 below. Gate your app on launch You don't want to call Gumroad on every launch, and you want the app to survive a flaky connection. LicenseGate caches the result and re-checks periodically: const path = require('node:path'); const { LicenseGate } = require('gumroad-license-lite'); const gate = new LicenseGate({ productId: 'YOUR_PRODUCT_ID', storageFile: path.join(app.getPath('userData'), 'license.json'), recheckEveryDays: 3, offlineGraceDays: 14, }); // on your activation screen: await gate.activate(userEnteredKey); // on every launch: const status = await gate.check(); if (!status.licensed) showActivationScreen(); The 3 gotchas "Valid" isn't the same as "exists." A refunded or charged-back sale still has a real, working key. If you only check that the key exists, people can buy, copy the key, refund, and keep your app forever. Always check the refund / dispute / subscription flags (the helper above does this for you). The uses counter is global, not per-device. Gumroad tracks a uses count, but it can't tell you which
This is a submission for the June Solstice Game Jam . What I Built Solstice Cipher is a small browser puzzle game about the longest day, code-breaking, and the turning point between signal and shadow. The player rotates mirrors to route a solstice beam through every cipher node before landing on the final beacon. Each level is a tiny circuit of light: if the beam misses a cipher gate, the beacon does not unlock. The game is inspired by a few June themes from the challenge prompt: the June solstice and the long arc of daylight light versus darkness turning points Alan Turing, code-breaking, and computational thinking Demo Demo video: watch in browser / direct MP4 Playable game: https://desciple88.github.io/solstice-cipher-devto-game-jam/ Source code: https://github.com/desciple88/solstice-cipher-devto-game-jam How It Works The game is a dependency-free HTML/CSS/JavaScript canvas app. The board is a 6x6 grid. A sunbeam enters from one side of the board, moves in one of four directions, and reflects when it hits a mirror: / turns east to north, south to west, and so on \ turns east to south, north to west, and so on Cipher nodes record whether the beam visited them. A level is solved only when the beam has touched all required cipher nodes and then reaches the beacon. Controls Click or tap a mirror to rotate it. Use Reset or press R to restart the level. Use Next or arrow keys to switch levels. Use Hint or press H if the path gets stuck. Why the Turing Angle I wanted the Alan Turing category to feel like part of the mechanics, not just a label. The player is effectively debugging a simple signal machine: change one reflector, trace the path, see which gates activated, and iterate until the message resolves. It is not an Enigma simulator, but it borrows the feeling of signal routing, symbolic gates, and systematic code-breaking. What I Used HTML CSS JavaScript Canvas 2D ffmpeg for the demo capture AI assistance was used while preparing the implementation and write-up. I
GitHub热门项目 | uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean. | Stars: 65,471 | 32 stars today | 语言: JavaScript
GitHub热门项目 | A self-hosted web application that lets you stream Live TV, Movies, and Series from your Xtream Codes or M3U provider directly in your browser. It's built with performance in mind and handles large libraries smoothly. | Stars: 1,333 | 49 stars today | 语言: JavaScript
GitHub热门项目 | Reverse engineering WhatsApp Web. | Stars: 6,475 | 22 stars today | 语言: JavaScript
Minesweeper feels intricate — numbers, cascading reveals, flags. Build it and you find it's a grid, a neighbour count, and one recursive function . This is Day 6 of my GameFromZero series. Each cell holds four facts const cell = { mine : false , open : false , flag : false , n : 0 }; n = how many of the 8 neighbours are mines. That number is all the player gets to reason about. Count neighbours once After scattering mines randomly, precompute every non-mine cell's n : let n = 0 ; neighbours ( r , c , ( rr , cc ) => { if ( cells [ rr ][ cc ]. mine ) n ++ ; }); cell . n = n ; Flood-fill is the whole trick When you open a cell with zero neighbouring mines, there's nothing dangerous nearby — so auto-open all 8 neighbours, and if any of those are also zero, they cascade. That's why one click can clear half the board. It's recursion: function open ( r , c ) { const cell = cells [ r ][ c ]; if ( cell . open || cell . flag ) return ; // base case cell . open = true ; if ( cell . n === 0 ) neighbours ( r , c , ( rr , cc ) => open ( rr , cc )); // recurse } This is the same algorithm behind the paint-bucket tool and maze region-filling. Flags + win/lose Right-click toggles a flag (and blocks accidental opens). Click a mine → lose. Win when opened cells = total − mines: if ( cell . mine ) gameOver (); if ( opened === R * C - M ) win (); That's the entire game. Master the state-step-draw loop once and every classic — Snake, Pong, Tetris, 2048, Minesweeper — is an evening each. ▶️ Play it + read the step-by-step breakdown: https://dev48v.infy.uk/game/day6-minesweeper.html Day 6 of GameFromZero.
I Built a 4-Sided Plot Area Calculator with 2D & 3D Visualization Most online plot calculators only work for simple rectangular plots. However, many real-world properties have four sides with different measurements, making area estimation much more difficult. That's why I built a 4-Sided Plot Area Calculator that allows users to enter the North, South, East, and West dimensions and instantly calculate the approximate plot area. 🔗 https://www.premiumconverters.com/plot-area-calculator Features 📐 Supports irregular 4-sided plots 🏠 Calculates area in Marla, Kanal, Acres, and more 🖼️ Interactive 2D top-down visualization 🏗️ Isometric 3D plot rendering 📏 Feet & inches input support 📱 Mobile-friendly experience Why I Built It In many countries, especially in South Asia, property dimensions are often recorded as side measurements rather than perfect geometric shapes. Existing tools rarely address this use case properly. I wanted to create a simple solution that homeowners, buyers, real estate professionals, and developers could use without needing complex surveying software. The Result The calculator transforms four side lengths into a practical estimate while providing visual feedback that helps users better understand their property's shape. Building tools that solve real-world problems is one of the most rewarding parts of software engineering. Have you ever built a niche tool that unexpectedly helped thousands of users?
Hello Dev Community! 👋 It is officially Day 26 of my journey to master the MERN stack! Today, I continued with Lecture 9 of Apna College's JavaScript playlist with Shradha Didi, transitioning from raw prototype object manipulation into modern ES6 structural design: Classes and Inheritance . Yesterday we saw how single objects share methods; today I learned how to create scalable blueprints to manufacture objects efficiently. 🧠 Key Learnings From JS Lecture 9 (Classes & OOP) I explored the professional layout of Object-Oriented Programming (OOP) in modern JavaScript: 1. What is a Class and a Constructor? A class is a standardized blueprint for creating objects. Inside every class, we can define a special method called a constructor() . The constructor triggers automatically the exact moment a new object is instantiated using the new keyword. It is the standard place to initialize instance properties dynamically. javascript class Car { constructor(brand, hp) { this.brandName = brand; this.horsepower = hp; } } let myCar = new Car("Toyota", 180); // Instantiates a fresh object instantly
The obsession with centralizing heavy compute on backend servers is a massive bottleneck for both cost and latency. In 2026, as more applications move to the edge, developers are realizing that the user's browser is an incredibly powerful, untapped compute engine. Recently, I challenged myself to build a free live chess game analyzer for my developer utility suite, CipherKit. The traditional architecture for this requires passing FEN strings to a dedicated backend cluster running the Stockfish engine, which introduces network latency and scales operational costs linearly. I wanted to achieve a 100% client-side, zero-latency experience. Here is how I offloaded the heavy lifting entirely to the browser edge. The Architecture: WASM + Web Workers Running a heavy calculation engine directly in JavaScript instantly blocks the main UI thread. To achieve a flawless 60fps UI, I completely decoupled the state from the computation. The UI Thread: Handles strict DOM rendering, board states, and piece animations. The Worker Thread: Instantiates the Stockfish engine via WebAssembly within the browser's memory. When a live game update occurs, the main thread fires a simple FEN payload via worker.postMessage() . The Worker processes the deep-line evaluations (Depth 20+) asynchronously in the background. It then streams the evaluation lines back to the main thread without causing a single micro-freeze. The Result By treating the browser as the edge compute layer, the tool achieves: Zero Server Latency: Bypassing API rate limits and network bottlenecks. $0 Infrastructure Cost: Heavy compute is crowd-sourced to the user's local device. Absolute Privacy: Sensitive payloads never leave the browser. If you want to see this local asynchronous thread management in action, you can test the live analyzer (and inspect the network tab) here: 👉 CipherKit Live Chess Analyzer Are you offloading heavy computations to the client side in your current projects, or are you still relying on traditional
A few weeks ago I shipped a feature I'd been putting off because it felt like it needed a backend: subscribable calendar feeds. "Add this holiday to Google Calendar." "Subscribe to all your country's public holidays so they show up in Apple Calendar forever." Every calendar competitor has this. My site had none. The catch: the whole thing is a static export — next build produces a folder of HTML/CSS/JS that I drop on Cloudflare Pages. No server, no API routes at request time, no ISR. So how do you serve a .ics feed that a calendar app polls every few hours? Turns out you don't need a server at all. Here's the approach, the RFC 5545 gotchas that bit me, and the parts I'd tell my past self. The "aha": a feed is just a file A .ics subscription feed is not a live API. It's a static text file that calendar clients re-fetch on a schedule. So for a static site, the idiomatic move is a post-build emitter : after next build , run a Node script that walks your data and writes assets straight into out/ . # scripts/deploy.sh npx next build node scripts/emit-feeds.mjs # writes .ics + .json into out/ That's the entire architecture. The emitter reads the same JSON the pages render from, so the feeds can never drift out of sync with the site — there's one source of truth. It emits: a per-year feed ( holidays-de-2026.ics ) a per-holiday feed (one event, for the "download this day" button) an all-years subscription feed (the one you point webcal:// at) and, almost for free in the same loop, a JSON API under out/api/ No new pages, no new routes. Just files. RFC 5545: all-day events are sneakier than they look I assumed an all-day event on Jan 1 would be DTSTART:20260101 , DTEND:20260101 . Wrong. DTEND is exclusive. A one-day all-day event ends on Jan 2 : BEGIN:VEVENT UID:de-2026-neujahr@calendana.com DTSTAMP:20260614T101500Z DTSTART;VALUE=DATE:20260101 DTEND;VALUE=DATE:20260102 SUMMARY:Neujahr TRANSP:TRANSPARENT CATEGORIES:Holiday END:VEVENT Get this wrong and some clients render a ze
Working with complex JSON payloads can quickly become a nightmare. You end up chaining .map() , .filter() , and .reduce() calls across multiple lines just to pull out a few nested values. Add optional chaining to avoid crashes and the code becomes nearly unreadable. There is a cleaner way - JSONata . It is a compact, purpose-built query and transformation language for JSON data. Think of it as XPath for XML, but designed from the ground up to work with JSON objects and arrays. What is JSONata? JSONata is an open-source project originally created by Andrew Coleman at IBM. It gives developers a declarative syntax to extract and reshape JSON data without writing procedural JavaScript loops. Where vanilla JS might take 15 lines, a JSONata expression often takes one. It is available as an npm package and integrates naturally into Node.js and TypeScript projects. Simple Path Navigation The foundation of JSONata is its dot-notation path traversal. Given a nested JSON object, you simply trace the path to the value you need: customer.address.city This returns the city value without any need for null checks or defensive coding. JSONata handles missing properties gracefully by returning undefined rather than throwing errors. Automatic Array Mapping When JSONata encounters an array during path traversal, it automatically maps across all items. There is no need to write an explicit .map() call: customer.orders.product This returns an array of all product names from every order in one clean expression. Inline Filtering You can filter arrays directly using bracket notation with a condition: customer.orders[price > 1000].product This returns only the products from orders where the price exceeds 1000. No .filter() callback required. Built-in Aggregation Functions JSONata ships with a solid set of built-in functions for math, strings, and arrays. Aggregating a set of values is straightforward: $sum(customer.orders.price) Other useful functions include $count() , $average() , $string(
GitHub热门项目 | An open source collection of animated, interactive & fully customizable React components for building memorable websites. | Stars: 41,003 | 91 stars today | 语言: JavaScript
What This Repository Is A complete, structured, beginner-friendly Node.js learning path. 30 sessions. Each session has Clear learning objectives Step-by-step explanations Working code examples Practice exercises Interview questions Summary of key points No fluff. No assumptions. Just code. The Complete Curriculum Phase 1 - Node.js Fundamentals (Sessions 1-5) Session Topic What You Will Build 01 Introduction to Node.js Your first Node.js program 02 Project Setup and npm package.json, node_modules 03 How Node.js Works Event loop, blocking vs non-blocking 04 Modules and Imports Your first custom module 05 File System Module Read, write, update, delete files Sample code from Session 05 const fs = require ( " fs " ); // Create a file fs . writeFileSync ( " student.txt " , " Welcome To Node.js " ); // Read the file const data = fs . readFileSync ( " student.txt " , " utf8 " ); console . log ( data ); // Welcome To Node.js // Append to file fs . appendFileSync ( " student.txt " , " \n New line added " ); // Delete file fs . unlinkSync ( " student.txt " ); Phase 2 - Core Modules (Sessions 6-10) Session Topic What You Will Build 06 Path Module Cross-platform file paths 07 OS Module System information 08 Events and EventEmitter Custom event handling 09 HTTP Module Create a server 10 Multi-Route Server Multiple routes, JSON responses Sample code from Session 10 const http = require ( " http " ); const server = http . createServer (( req , res ) => { if ( req . url === " / " ) { res . end ( " Home Page " ); } else if ( req . url === " /about " ) { res . end ( " About Page " ); } else if ( req . url === " /products " ) { res . setHeader ( " Content-Type " , " application/json " ); res . end ( JSON . stringify ([{ id : 1 , name : " Laptop " }])); } else { res . statusCode = 404 ; res . end ( " Page Not Found " ); } }); server . listen ( 3000 ); Phase 3 - Building REST APIs (Sessions 11-15) Session Topic What You Will Build 11 CRUD with Dummy Data Complete REST API using array 12