让天下没有难学的编程 |

全部资讯


An introduction to testing React components with Enzyme 3

In today’s post we’ll introduce the AirBnB library Enzyme for testing React applications. We’ll do this using a test driven development (TDD) approach. That is, we’ll write the tests first, watch them fail, and then build the React component out to fix the tests, before then writing more. We’ll then consider how we can refactor code whilst running the tests to confirm we haven’t made any errors. In reality, I don’t often write components from scratch in a TDD way, however I will often use TDD to replicate an existing bug in a component to first see the bug in action, and then fixing it. Feedback via test results on the command line is often much quicker than browser refreshes and manual interactions, so writing tests can be a very productive way to improve or fix a component’s behaviour. Set up I’ll be using a brand new React app for this tutorial, which I’ve created with create-react-app. This comes complete with Jest, a test runner built and maintained by Facebook. There’s one more dependency we’ll need for now - Enzyme. Enzyme is a suite of test utilities for testing React that makes it incredibly easy to render, search and make assertions on your components, and we’ll use it extensively today. Enzyme also needs react-test-renderer to be installed (it doesn’t have it as an explicit dependency because it only needs it for apps using React 15.5 or above, which we are). In addition, the newest version of Enzyme uses an adapter based system where we have to install the adapter for our version of React. We’re rocking React 16 so I’ll install the adapter too: yarn add -D enzyme react-test-renderer enzyme-adapter-react-16 The -D argument tells Yarn to save these dependencies as developer dependencies. You can read more about installing Enzyme in the docs. Enzyme setup You also need to perform a small amount of setup for Enzyme to configure it to use the right adapter. This is all documented in the link above; but when we’re working with an application created by create-react-app, all we have to do is create the file src/setupTests.js. create-react-app is automatically configured to run this file before any of our tests. import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; configure({ adapter: new Adapter() }); If you’re using an older version of React in your projects but still want to use Enzyme, make sure you use the right Enzyme adapter for the version of React you’re using. You can find more on the Enzyme installation docs. create-react-app is configured to run this file for us automatically when we run yarn test, so before our tests are run it will be executed and set up Enzyme correctly. If you’re not using create-react-app, you can configure Jest yourself to run this file using the setupTestFrameworkScriptFile configuration option. The Hello component Let’s build a component that takes a name prop and renders <p>Hello, name!</p> onto the screen. As we’re writing tests first, I’ll create src/Hello.test.js, following the convention for test files that create-react-app uses (in your own apps you can use whichever convention you prefer). Here’s our first test: import React from 'react'; import Hello from './Hello'; import { shallow } from 'enzyme'; it('renders', () => { const wrapper = shallow(<Hello name="Jack" />); expect(wrapper.find('p').text()).toEqual('Hello, Jack!'); }); We use Enzyme’s shallow rendering API. Shallow rendering will only render one level of components deep (that is, if our Hello component rendered the Foo component, it would not be rendered). This helps you test in isolation and should be your first point of call for testing React components. You can run yarn test in a React app to run it and have it rerun on changes. If you do that now, you’ll see our first error: Cannot find module './Hello' from 'Hello.test.js' So let’s at least define the component and give it a shell that renders nothing: import React from 'react'; const Hello = props => { return null; }; export default Hello; Now we get a slightly cryptic error: Method “text” is only meant to be run on a single node. 0 found instead. Once you’ve used Enzyme a couple of times this becomes much clearer; this is happening because we’re calling wrapper.find('p') and then calling text() on that to get the text, but the component is not rendering a paragraph. Let’s fix that: const Hello = props => { return <p>Hello World</p>; }; Now we’re much closer! expect(received).toEqual(expected) Expected value to equal: "Hello, Jack!" Received: "Hello World" And we can make the final leap to a green test: const Hello = props => { return <p>Hello, {props.name}!</p>; }; Next up, let’s write a test to ensure that if we don’t pass in a name, it defaults to “Unknown”. At this point I’ll also update our first test, because it('renders', ...) is not very descriptive. It’s good to not care too much about the name of the first test you write, and focus on the implementation, but once you’re more comfortable with what you’re testing and beginning to expand your test suite, you should make sure you keep things organised. With our second test, we’re failing again: it('renders the name given', () => {...}) it('uses "Unknown" if no name is passed in', () => { const wrapper = shallow(<Hello />); expect(wrapper.find('p').text()).toEqual('Hello, Unknown!'); }); expect(received).toEqual(expected) Expected value to equal: "Hello, Unknown!" Received: "Hello, !" But we can now write our first pass at the implementation to fix it: const Hello = props => { return <p>Hello, {props.name || 'Unknown'}!</p>; }; And now the test is green we’re free to refactor. The above is perfectly fine but not the way it’s usually done in React. Some might choose to destructure the props argument and give name a default value: const Hello = ({ name = 'Unknown' }) => { return <p>Hello, {name}!</p>; }; But most of the time when working with React components I’ll use the defaultProps object to define the defaults. I’ll also set the component’s propTypes: import React from 'react'; import PropTypes from 'prop-types'; const Hello = props => { return <p>Hello, {props.name}!</p>; }; Hello.propTypes = { name: PropTypes.string, }; Hello.defaultProps = { name: 'Unknown', }; export default Hello; And all our tests are still passing. Conclusion That brings our first look at testing React with Enzyme 3 to an end. In future tutorials we’ll dive further into what Enzyme has to offer and see how we can test components of increasing complexity.收起
显示全部文字 查看全文
作者/
时间/2017-12-12 00:00:00

Wedging State Data

In React, state must not be mutated directly, or, to say it in a dev-friendly way, state needs to be immutable. We don’t have to know all the inner-workings of React state to follow this guideline. It’s kind of like driving a car — if you want to stop or slow down, there is a set method of pushing the brake pedal, but we don't really need to know exactly how the brakes work to enjoy the benefits of using the pedal. You wouldn’t pull up the floor board and jam a crowbar into the drive shaft while throttling the hand brake. Nor would you toss an anchor out the window and hope it grabs onto something to stop the car. These methods may actually work, but will produce some strange (and dangerous) side effects and behaviors. Better to use the brakes and not mutate state. For this example, say the data in our state looks something like this: messages: [ {message: “First message”}, {message: “Second message”}, {message: “Third message”}, {message: “Fourth message”} ] If we want to add a new message onto the end, we would use concat: this.setState(prevState => ({ messages: prevState.messages.concat(data.message) })) Pretty straight forward. But what happens when we want to wedge new data in-between old data? For example, under the second message. This gets complicated as we can’t concat or push because we would mutate the state. First, we have to setup our click event which will set a variable to the item id, in this case we’ll be using data-id: handleClick = (event) => { let selected = event.target.dataset.id } Next, copy the entire state using Object.assign: handleClick = (event) => { let selected = event.target.dataset.id let copyState = Object.assign({}, this.state) } In order to place our new message in between the current messages, we need to grab all of the messages before and all of the messages after. To accomplish this, we use slice(): handleClick = (event) => { let selected = event.target.dataset.id let copyState = Object.assign({}, this.state) let leftState = copyState.messages.slice(0, selected + 1) let rightState = copyState.messages.slice(selected + 1) } Finally, to complete our new object, we can use the ES6 spread operator and put everything together into a new array: handleClick = (event) => { let selected = event.target.dataset.id let copyState = Object.assign({}, this.state) let leftState = copyState.messages.slice(0, selected + 1) let rightState = copyState.messages.slice(selected + 1) let newState = [...leftState, {data.message}, …rightState] this.setState({ messages: newState }) } This solution works well for our simple example. Things get more complicated with nested data when a deep copy is necessary to update state. I’ll cover that topic in another post.收起
显示全部文字 查看全文
作者/Daniel Warren
时间/2017-12-11 08:59:36

How I concluded to my portfolio website

It was about time to start rebuilding my personal-portfolio-website. My previous one didn’t seem to comply with my aesthetics and needs. A few weeks ago I asked myself several questions. 1.What is my goal? My goal is to create an online presence that represents my personality, people can easily browse my previous works in detail, read articles or watch videos and contact me easily. 2.What problems am I trying to solve? I can’t use my current website as a blog/portfolio as it’s not convenient to add details in my projects.I can only add some images and links to them. I have to rethink my needs, and the things I want to show. I want a better connection with people in the web. 3. What about some inspiration? Yes, inpiration is always great but I shouldn’t let other websites be all over my head. I have to create my own ideas based on the things I like. In that way I will present my own personality. Research: Personal sites with an aesthetically pleasing design (in no particular order) Darian Rosebrook Alan M Shen Eric Bue Adham Dannaway Research: Things I must not miss to include in a personal portfolio site * At least some basic info about myself * Links to my works * A way (or more) for people to contact me * Social platforms What do I really want to show? As I stated earlier, I want to showcase my personality, I want to give details about my works and the projects I ‘m proud of. I want to share my knowledge through articles and videos. I want to connect with people and make it easy for them to reach me. To whom am I referring to? To answer that question I decided to think as UX designer building a new product. I had to make some personas. User Personas represent real, living and breathing people who will engage with your product. While individuals featured on a persona are technically hypothetical, the information on the document should not be hypothetical. - by Xtensio In this part I am not going to get into a lot of detail... I decided to have three types of personas based on who would browse my website. * An employer (a developer manager, a hiring manager): This person wants to get some quick information. She is busy, has a lot of meetings, emails and calls. She certainly won’t have the time to view in detail all of my projects and posts. Probably a manager won’t spent more than a few minutes on my site. * Someone searching for a specific project/post (like an article, a tutorial, a video): This group of people is interesting for that project and that post, not for my bio or my most recent video tutorial. If they find me interesting they will read more, if not they will close the tab. * Someone who randomly found me: (maybe she googled my name, found me on twitter/youtube and wanted to learn more). This person is going to search my bio, my projects and posts. She could spend seconds to minutes browsing the site. Time for decisions Custom design VS using a template That was a tough one. I would love to create and code my own design and have a unique portfolio but it’s not a current priority. A template/theme, using a CMS (Wordpress, Joomla, Drupal), is a quicker and easier solution. Since I already have a drupal-website, installation and configuration should come pretty easy. On the other hand, I wasn’t going to let a template define my website. Based on what I was looking for, I designed a simple prototype. My theme should be a clean, modern, elegant design, with plenty of room to display the portfolio and the blog posts. Choosing a theme I don’t remember how many hours/days I spend searching for the “perfect”, free or paid theme. I opened a lot of tabs to compare them more easily. After a lot of browsing, I found the “one”, meeting my criteria and pleasing my aesthetics. The “one” is called “mdeal responsive business” and is supported by Drupal 7. Installation, configuration and filling the pages After installing the theme, I configured the blocks, the panels, the pages and the css classes. I must have spent 3-4 days to make the theme look like my prototype. Ι spent almost a week to organize the menu, header, prefooter, footer and the main-part of home, about, portfolio, post and contact page. My site You can watch my short video about how I made my online portfolio website. Notes: 1.I am still writing my projects hence I am aware that portfolio section looks kinda empty. 2.My site is currently under v1.1, if you have any recommendations, please do share. Before you go, please subscribe to my youtube channel and if you liked that post follow my stories on Twitter. Thanks for reading, have an awesome day.收起
显示全部文字 查看全文
作者/Eleftheria Batsou
时间/2017-12-10 10:47:12

Learn more about vulnerability alerts

I personally hate the posts that include "considered harmful"…and yet, here we are. My first "considered harmful" post. Hopefully my last, but we're still young on the web. Github has launched security alerts recently, and as much as I hate to write, I think the first swing at it is considered harmful.收起
显示全部文字 查看全文
作者/
时间/2017-12-08 23:30:45

The 10 Best Free WordPress Themes For 2017

A collection of some of our favourite free WordPress themes for 2017.
查看全文
作者/Georgi Georgiev
时间/2017-12-04 23:34:15

Where do those node warnings come from?

This is a micro post with a tip that I'll need to remember again in the months to come. Node.js can emit warnings on the terminal saying that a rejected promise wasn't caught, or calling an asynchronous function without callback is deprecated.But where exactly is the original call that causes that warning?收起
显示全部文字 查看全文
作者/
时间/2017-12-04 20:26:09

Markup as function

If you are writing React applications you probably know about higher order components or render props (which by the way I think is kind of a form of higher order component pattern). In both cases we have a component that encapsulates logic and passes props down to children. Recently at work we came to the idea that we may push this further and represent some functionalities which are out of React in the same fashion - with a single tag in our components tree.收起
显示全部文字 查看全文
作者/
时间/2017-12-01 06:00:00

Reducing Chrome crashes caused by third-party software

Roughly two-thirds of Windows Chrome users have other applications on their machines that interact with Chrome, such as accessibility or antivirus software. In the past, this software needed to inject code in Chrome in order to function properly; unfortunately, users with software that injects code into Windows Chrome are 15% more likely to experience crashes. With Chrome extensions and Native Messaging, there are now modern alternatives to running code inside of Chrome processes. Starting in July 2018, Chrome 68 will begin blocking third-party software from injecting code into Chrome on Windows.These changes will take place in three phases. In April 2018, Chrome 66 will begin showing affected users a warning after a crash, alerting them that other software is injecting code into Chrome and guiding them to update or remove that software.In Chrome 66 a warning will be shown to users with third-party software that injects into Chrome. In July 2018, Chrome 68 will begin blocking third-party software from injecting into Chrome processes. If this blocking prevents Chrome from starting, Chrome will restart and allow the injection, but also show a warning that guides the user to remove the software. Finally, in January 2019, Chrome 72 will remove this accomodation and always block code injection.While most software that injects code into Chrome will be affected by these changes, there are some exceptions. Microsoft-signed code, accessibility software, and IME software will not be affected. As with all Chrome changes, developers are encouraged to use Chrome Beta for early testing.Fewer crashes means more happy users, and we look forward to continuing to make Chrome better for everyone.Posted by Chris Hamilton, Chrome Stability Team收起
显示全部文字 查看全文
作者/Chrome Blog
时间/2017-12-01 02:33:25

10 Useful Git Tips

In this tutorial we share with you a collection of tips that will help you manage your git repositories.
查看全文
作者/Georgi Georgiev
时间/2017-11-24 20:03:54

Meet the JavaScript pattern of the year or how to handle async like a boss

Sometimes when you learn something new you get really excited. Excited to that level so you want to teach it to someone. That is the case with the concept which I found a couple of months ago. It is an implementation of the command pattern using generators. Or the well known saga used in the redux-saga library. In this article we will see how the idea makes our asynchronous code simpler and easy to read. We will also implement it ourself using generators.收起
显示全部文字 查看全文
作者/
时间/2017-11-24 06:00:00

#361: Currying Is Not Idiomatic in JavaScript

This week's JavaScript news — Read this e-mail on the Web JavaScript Weekly Issue 361 — November 17, 2017 How to Reduce the Cost of JavaScript An increasing reliance on JS can result in needless performance issues for our users. Addy Osmani looks at how a little discipline can help. Addy Osmani How Redux Works: A Counter-Example An attempt to demystify Redux, a popular state container for JavaScript apps, with a ‘backwards approach’. Dave Ceddia Luxon: A Chainable Wrapper for JavaScript Dates and Times From the creators of Moment.js, Luxon provides DateTime, Duration, and Interval types, as well as parsing and formatting for common formats. JS Foundation Want to ship better React Native apps faster? Meet App Center. From the creators of CodePush. Ship iOS and Android apps faster by connecting your app’s repo and automating the rest. App Center builds your app in the cloud, tests it on real iOS devices, releases to beta testers, app stores or CodePush, and monitors with crash reports and analytics. Sign up now. Microsoft   Sponsor Currying Is Not Idiomatic in JavaScript The good doctor explains "why, in my opinion, currying is not a good fit for JavaScript.” Dr. Axel Rauschmayer GitHub Introduces Security Alerts for JS Projects It’s possible to track your project’s dependencies directly in GitHub and if you do, GitHub can now notify you of vulnerabilities in them automatically. GitHub WebAssembly Support Now in All Major Browsers Apple and Microsoft are shipping WebAssembly support in the latest versions of Safari and Edge so all 4 major browsers can now run code compiled to the wasm format. Judy DeMocker ECharts: Powerful Charting and Visualization for the Browser Been around a while but has grown a lot and now has extensions for major frameworks. Demos here. Baidu Jobs craigslist seeks JavaScript Developers (San Francisco, CA)CL seeks JS developers to join our small (~50) team. Come help us save the world, or at least our corner of the Internet. craigslist Web Client EngineerJoin a growing engineering team that builds highly performant video apps across Web, iOS, Android, FireTV, Roku, tvOS, Xbox and more. Discovery Digital Media Want a New JavaScript Job Before the New Year?Try Underdog.io, where hundreds of the best tech companies go to find JavaScript talent. Companies email you directly as soon as next Monday. Underdog.io Can't find the right job? Want companies to apply to you? Try Hired.com.-->In Brief VueConf US 2018: March 26–28, 2018 in New Orleans, USA news The VueConf.US 2018 call for proposals is now open, and closes December 1.VueConf US A Brief Introduction to Symbols, Generators and Streams tutorialRubens Pinheiro Gonçalves Cavalcante Learn and Understand JavaScript’s Reduce Function tutorial Or Array.prototype.reduce(), more specifically.Brandon Morelli Building a NodeJS App with MongoDB Atlas and AWS ECS (Part 1) tutorial It's that time of year again. This is the first post in our annual "Road to AWS re:Invent" blog series.mongodb  Sponsor Easy ES6 Goodies for Busy JavaScript Developers tutorial “a good basic introduction to three of the most useful ES6 goodies”Michelle Gienow Build a Server-Side Rendered Vue App with Nuxt.js tutorialChimezie Enyinnaya Developing a Chrome Extension using Angular 4 tutorialJakub Kaczmarek Start Using Babel 7 Beta Today: What's New and How tutorialJeff Dolle Web Workers Can Be ES6 Modules Too tutorial OK, Chrome doesn’t support it yet, but work is underway.Jeff Schiller CircleCI 2.0 Language Guide: JavaScript tutorial New to CircleCI 2.0? Read our JavaScript Language Guide for a detailed explanation of our configuration.CircleCI  Sponsor Angular Productivity Tips for WebStorm IDE Users tutorialJurgen Van de Moere Browser Automation Revisited: Meet Puppeteer tutorial node Puppeteer is a Node library that provides an API to control headless Chrome.Gergely Nemeth Recover Gracefully with React 16 Error Boundaries tutorialROLLBAR  Sponsor Converting 600k Lines to TypeScript in 72 Hours story Specifically, from Google Closure-annotated JS.Lucidchart How GitLab Uses Vue: One Year Later storyJacob Schatz High Performance JS in V8: How V8 Is Faster Than Ever video A 20 minute tour of V8’s latest code-generation architecture.Peter Marshall Neutronium: Build .NET Desktop Apps using HTML, CSS and JavaScript toolsNeutronium react-scroll-to: Scroll to Position in React codeDylan Paulus remoteStorage.js 1.0.0: Local Data Storage with Remote Syncing code A project that’s as old as this newsletter. bent: Functional HTTP Client for Node with async/await Support code nodeMikeal Rogers Curated by Peter Cooper and published by Cooperpress. Like this? You may also enjoy: FrontEnd Focus : Node Weekly : React Status Stop getting JavaScript Weekly : Change email address : Read this issue on the Web © Cooperpress Ltd. Fairfield Enterprise Centre, Lincoln Way, Louth, LN11 0LS, UK 收起
显示全部文字 查看全文
作者/
时间/2017-11-17 00:00:00

15 Interesting JavaScript and CSS Libraries for November 2017

This November's collection is packed with awesome free resources including some powerful CSS frameworks and JS tools.
查看全文
作者/Georgi Georgiev
时间/2017-11-14 19:44:14

Expanding user protections on the web

One of the advantages of the web is that it allows developers to create any type of experience they can imagine, which has led to the rich diversity of content available on the web today. While most content producers are interested in providing excellent experiences for their users, we've found that a small number use the flexibility and power of the web to take advantage of users and redirect them to unintended destinations. 1 out of every 5 feedback reports from Chrome users on desktop mention encountering some type of unwanted content, and we take this feedback seriously when considering how to improve Chrome. Following on from features like Chrome's pop-up blocker and autoplay protections, over the next few releases we'll be rolling out three new protections designed to give users all the web has to offer, but without many of these types of unwanted behaviors.One piece of feedback we regularly hear from users is that a page will unexpectedly navigate to a new page, for seemingly no reason. We've found that this redirect often comes from third-party content embedded in the page, and the page author didn't intend the redirect to happen at all. To address this, in Chrome 64 all redirects originating from third-party iframes will show an infobar instead of redirecting, unless the user had been interacting with that frame. This will keep the user on the page they were reading, and prevent those surprising redirects.An example of a redirect being blocked on a test site. The iframes embedded in the site are attempting to navigate the page to an unintended destination, but Chrome prevents the redirect and shows an infobar.When the user interacts with content, things can also go wrong. One example that causes user frustration is when clicking a link opens the desired destination in a new tab, while the main window navigates to a different, unwanted page. Starting in Chrome 65 we'll also detect this behavior, trigger an infobar, and prevent the main tab from being redirected. This allows the user to continue directly to their intended destination, while also preserving the context of the page they came from.Finally, there are several other types of abusive experiences that send users to unintended destinations but are hard to automatically detect. These include links to third-party websites disguised as play buttons or other site controls, or transparent overlays on websites that capture all clicks and open new tabs or windows. Two types of abusive experiences where a deceptive site control appears to do one thing, but has a different behavior when clicked. One looks like a play button on a video but sends the user to an unwanted download when clicked (left), and the other looks like a close button but instead opens unwanted pop-up windows (right).Similar to how Google Safe Browsing protects users from malicious content, starting in early January Chrome's pop-up blocker will prevent sites with these types of abusive experiences from opening new windows or tabs. To help site owners prepare for this change, today we're also launching the Abusive Experiences Report alongside other similar reports in the Google Search Console. Site owners can use the report to see if any of these abusive experiences have been found on their site and improve their user experience. Otherwise, abusive experiences left unaddressed for 30 days will trigger the prevention of new windows and tabs.Together, these protections will dramatically improve users' web browsing experiences while still allowing them access to all that the web has to offer. Posted by Ryan Schoen, Product Manager收起
显示全部文字 查看全文
作者/Chrome Blog
时间/2017-11-11 02:01:57

Getting from Redux to a state machine

This article is about Stent - a Redux-liked library that creates and manages state machines. Stent implements some of the Redux’s core ideas and in fact looks a lot like it. At the end of this post we will see that both libraries have a lot in common. Stent is just using state machines under the hood and eliminates some of the boilerplate that comes with Redux’s workflow.收起
显示全部文字 查看全文
作者/
时间/2017-11-10 06:00:00

15 Awesome React Components

In this article we share with you a collection of some of our favorite React components.
查看全文
作者/Georgi Georgiev
时间/2017-11-07 20:02:33

9 Free Icon Packs For Web Developers

Our favorite icon sets for web use, including some icon fonts, SVGs, and CSS-only icon packs.
查看全文
作者/Georgi Georgiev
时间/2017-11-01 18:33:51

Chrome 63 Beta: Dynamic module imports, async iterators and generators, Device Memory API, and permissions UI changes

Unless otherwise noted, changes described below apply to the newest Chrome Beta channel release for Android, Chrome OS, Linux, Mac, and Windows.Dynamic module importsCurrently, importing JavaScript modules is completely static, and developers cannot import modules based on runtime conditions, like whether a user is logged in. Starting in this release, the import(specifier) syntax now allows developers to dynamically load code into modules and scripts at runtime. This  can be used for lazy loading a script only when it’s needed, which improves performance of the application. button.addEventListener('click', event => {    import('./dialogBox.js')    .then(dialogBox => {        dialogBox.open();    })    .catch(error => {        /* Error handling */    });});The code example above shows how to use the import(specifier) function to import JavaScript after an event. Async iterators and generatorsWriting code that does any sort of iteration with async functions can be inelegant. The new async generator functions using the async iteration protocol are now available to help developers streamline the consumption or implementation of streaming data sources. Async iterators can be used in for loops and also to create custom async iterators through async iterator factories. async function* getChunkSizes(url) {  const response = await fetch(url);  for await (const chunk of streamAsyncIterator(response.body)) {    yield chunk.length;  }} The code example above shows how to use async iterators to writer cleaner code for streaming fetches, using the streamAsyncIterator function. Device Memory APIIt’s challenging for developers to create one user experience that can work across all devices, due to varying device capabilities. The new Device Memory JavaScript API helps developers with this challenge by using the total RAM on a user’s machine to provide insights into device constraints. This insight enables developers to tailor content at runtime in accordance with hardware limitations. For example, developers can serve a “lite” app to users on low-end devices, resulting in better experiences and fewer frustrations. The Device Memory API can also be used to add context to metrics, such as the amount of time a task takes to complete in JavaScript, through the lens of device memory. Permissions UI changesWhen websites need special permissions from a user, they trigger a permission request. Currently these permission requests appear in Chrome for Android as ignorable banners at the bottom of the screen, and developers often show them without considering whether the user has the appropriate context to grant the permission. This results in a distracting user experience, and users ignore or temporarily dismiss these permission prompts more than 90% of the time.In Chrome 59, we started to address this problem by temporarily blocking a permission if the user dismisses the request three times. As a next step, in this release Chrome for Android now presents permission requests as modal dialogs. This change reduces the overall number of permission prompts by 50%. It also makes users 5 times more likely to accept or deny requests, rather than temporarily dismissing or repeatedly ignoring them. To ensure users understand the permission request, developers should present users with permission requests at an appropriate time, as we’ve found that users were 2.5 times more likely to grant permission to a site that ask for permissions with context. Other features in this releaseBlink > BindingsTo improve interoperability, a TypeError is now thrown for EventTarget.addEventListener and removeEventListener when the callback passed is not an EventListener, null, or undefined.  Blink > CSS Developers can now make pixel-level adjustments using the new Q length unit, which is especially useful on small viewports. Developers can now prevent apps from using Chrome’s pull-to-refresh feature or create custom effects using  overscroll-behavior, which allows changing the browser’s behavior once the scroller has reached its full extent. Blink > Fontsfont-variant-east-asian is now supported, allowing developers to control the usage of alternate glyphs for East Asian languages like Japanese and Chinese.Blink > HTMLTo improve interoperability, Chrome will fire  beforeprint and afterprint events as part of the printing standard, allowing developers to to annotate the printed copy and edit the annotation after the printing command is done executing. Blink > JavaScript Using Promise.prototype.finally, a callback can now be registered to be invoked after a Promise has been fulfilled or rejected. The Intl.PluralRules API allows developers to build applications that understand pluralization of a given language by indicating which plural form applies for a given number and language.Blink > MediaStreamMediaStreamTrack.applyConstraints() is now supported for local video MediaStreamTracks, including tracks obtained from getUserMedia(), capture from media elements or screen capture.Blink > NetworkVersion 2 of NT LAN Manager (NTLM) API is now shipped, enabling applications to authenticate remote users and provide session security when requested by the application. Blink > SensorThanks to contributors from engineers at Intel, an Origin Trial is now available that exposes the following sensors via the new Generic Sensors API syntax: Accelerometer, LinearAccelerationSensor, Gyroscope, AbsoluteOrientationSensor, and RelativeOrientationSensor.Blink > StorageThe localStorage and sessionStorage API's now use getItem() rather than an anonymous getter, so attempting to access a key using getItem() will now return null rather than undefined. Thanks to Intel for the contribution! To improve developer experience, the methods on sessionStorage and localStorage such as getItem(), removeItem(), and clear() are now enumerable. Thanks to Intel for making this happen!UI > Browser > Mobile (Android) display: minimal-ui is now supported by Chrome on Android, enabling developers to display a UI similar to Chrome Custom Tabs for users. Deprecations and interoperability improvementsBlink > BindingsTo improve interoperability, instance properties with a Promise type now return a rejected promise instead of throwing an exception. Blink > CSSThe /deep/ or >>>, selector, as well as ::shadow, are now removed from CSS dynamic profile, following their deprecation in Chrome 45. Blink > DOMTo improve interoperability, HTMLAllCollection, HTMLCollection, HTMLFormControlsCollection and HTMLOptionsCollection are no longer enumerable, so they are now left out of calls to Object.keys() or for-in loops. Posted by Sathya Gunasekaran, Lazily-Loaded Engineer收起
显示全部文字 查看全文
作者/Chrome Blog
时间/2017-11-01 00:30:24

Dear Dizzy

Dizzy. Our stripy cat. A stow away in Julie's handbag when we intended to only take home two cats - instead we left with three. Dizzy by name and truly dizzy by nature.
查看全文
作者/
时间/2017-10-31 02:19:17

You are managing state? Think twice.

Recently I started questioning the state management in React applications. I’ve made some really interesting conclusions and in this article I’ll show you that what we call a state management may not be exactly about managing state.收起
显示全部文字 查看全文
作者/
时间/2017-10-27 05:00:00

ES6: Default arguments

Default arguments in ES6, put simply: I'm a huge fan. I wanted to document a few of the ways I use default args and how they've made my old ES5 workarounds go away in favour of a much more elegant code design.收起
显示全部文字 查看全文
作者/
时间/2017-10-25 22:15:51