Make WordPress Core

Tagged: javascript Toggle Comment Threads | Keyboard Shortcuts

  • Dominik Schilling (ocean90) 7:28 pm on October 10, 2016 Permalink |
    Tags: , javascript   

    JavaScript Internationalization 


    Over the last few releases, WordPress has made huge steps in prioritizing internationalization and localization throughout around core. To name a few highlights: language packs for core, language packs for plugins and themes, a language chooser, just-in-time loading for translations, and a user-specific language setting. But core isn’t the only place improvements have been made.

    translate.wordpress.org is the platform for making WordPress available in as many languages as possible. Did you know that WordPress 4.6 is currently translated into 72 – s e v e n t y t w o – languages? Recently the number of unique translators passed the 10k mark. 🌎🌍🌏

    The platform is powered by GlotPress, a collaborative, web-based software translation tool.

    Internationalization is not a feature, it fixes a usability issue for many users whose primary language is not English. And that’s about 47% of our users.

    The next big thing

    As of today, WordPress doesn’t support a proper internationalization API in JavaScript. There are two, 4-year old tickets, #22229 and #20491, which request such an API. (The former one was closed as a duplicate of #20491 since an internationalization API in JavaScript should provide support for plurals by default.)

    And that’s what this post is about: JavaScript Internationalization.

    @swissspidy and I (@ocean90) have been thinking about and working on this topic, and now is the time to gather feedback on the direction and get help from everyone interested.

    As you may have noticed in the prequel, internationalization spans more than WordPress core. We’ve split the task into four areas: Core, GlotPress, wp-i18n-tools, and language packs.

    Jed and wp.i18n (Core)

    Since we didn’t want to reinvent any wheels, our proposal is to use Jed as the base library. Jed provides “Gettext Style i18n for Modern JavaScript Apps”.

    wp.i18n will be a wrapper for Jed and should be used by WordPress and plugins/themes. One of the biggest benefits of leveraging Jed is that the actual implementation is very similar to the one we already have for PHP code. The latest patch currently introduces these API functions:

    • wp.i18n.getLocale()
    • wp.i18n.loadLocaleData( data )
    • wp.i18n.addTranslations( domain, data )
    • wp.i18n.__( text, domain )
    • wp.i18n._x( text, context, domain )
    • wp.i18n._n( single, plural, number, domain )
    • wp.i18n._nx( single, plural, number, context, domain )
    • wp.i18n.esc_attr__( text, domain )
    • wp.i18n.esc_html__( text, domain )
    • wp.i18n.esc_attr_x( text, context, domain )
    • wp.i18n.esc_html_x( text, context, domain )
    • wp.i18n.numberFormat( number, decimals )
    To do
    • Rethink WP_Scripts::load_translation_file() and get_js_i18n_data(), add tests.
    • Get feedback on the proposed API. (That’s this post!)
    • Apply the new API in our JS files.
      • There’s a POC patch that can be worked upon.
      • Do not forget: Underscore templates.
    • Include date of json files in update requests for language packs.
      • See wp_get_installed_translations().
      • See wp_get_json_file_data(), maybe json_decode() might be enough for this case.
      • What’s the format for meta data? See this GitHub issue for discussion.
    • sprintf() in JavaScript – useful for core?

    GlotPress (translate.wordpress.org)

    Jed supports JSON for translation files. GlotPress currently doesn’t support exporting translations in a JSON format. But there is a pull request which adds the required functionality to GlotPress. The format is going to support “simple” JSON (key -> value) and a Jed 1.x compatible format. The latter will be used by wp.i18n.

    To do
    • Get the PR merged. Done. 🎉
    • Find a solution for the missing meta data, see the GitHub issue mentioned before.
    • To enable exports like “get all translations for file common.js”, the current filter system in GlotPress needs to be improved to support search only in file references and search for multiple file references.

    wp-i18n-tools (Meta)

    A script named MakePOT parses PHP files to extract the original strings and their file references. This script needs to be extended to also parse JavaScript files. A POC has been created.

    To do
    • Convert the POC into nice code with tests.
    • Fix #20881 because it’s important for the GlotPress export that all file references remain.

    Language Packs (Meta)

    Currently a language pack includes a .po and a .mo file. Support needs to be added so that a .json file gets bundled if a project has translations for JavaScript files.

    To do
    • Export Jed files when JS translations exist.
    • Include JSON file in language packs.
    • Update API to support version checks for JSON files.


    Thanks for reading, now it’s your turn. 🙂 Do you have any feedback? Are there things we should do differently? Do you have resources to help us? Please let us know in the comments!

    There are currently no meetings scheduled but we’re happy to discuss any topics in #core-i18n. Just say “Hi”!

  • Weston Ruter 11:04 am on January 26, 2015 Permalink
    Tags: , , javascript, , ,   

    Proposal: Customizer Transactions 

    You may be familiar with transactions in a database context. The idea is simple: once you start a transaction, any change made to the database in the current session will not be applied to other database sessions until a transaction COMMIT is done. Changes performed when the transaction is open will be reflected in any SQL SELECT queries made, and if you decide that you do not want to persist the changes in the transaction in the database, you can simply do ROLLBACK and the changes will be discarded. And actually WordPress already uses MySQL transactions, but only in unit tests: a rollback is done after each test is torn down to restore the database state for the next test.

    The parallels between database transactions and the WordPress Customizer are clear. When you open the Customizer you are starting a “settings transaction”. Any changes made to the settings in the Customizer get reflected in the preview only, and they get written (committed) to the database only when the user hits “Save & Publish”.

    As good as the Customizer currently is, the way it has been implemented means that there are limitations on what we can do with it.

    Current Limitations

    The existence of modified settings in the Customizer is restricted to the life of a browser window. When a user changes a control in the Customizer and a setting is modified (with transport=refresh), an Ajax request is made with the changed settings data POSTed to the previewed URL. The Customizer then boots up and adds the setting preview filters based on what it sees in $_POST['customized'] so that the changes are reflected when WordPress builds the page. When this Ajax response is received, the Customizer JS code then writes the response to the iframe via document.write().

    There are a few downsides to this current approach:

    One problem is that if the user navigates away from the Customizer, they lose their drafted settings. To get around this, an AYS dialog was added in #25439, but this still doesn’t account for browser crashes or system failures. It would be ideal if the settings could persist in the same way as when drafting a post.

    Another downside is that whenever the preview needs to refresh it has to re-send all the modified settings so that the Customizer preview will have them available to add to the filters, since the Customized settings data is not persisted in WordPress in any way. There’s a performance hit to continually send all data with each request, which was partially improved with #28580.

    Additional problems stem from the Ajax POST + document.write() approach to refreshing the preview. Since the Customizer iframe starts out at about:blank and the HTML is written to from the document at customize.php, much of the context for the document in the iframe gets inherited from the parent window. This means that window.location in the preview window is the same as in the parent window: /wp-admin/customize.php. Needless to say, this means that JavaScript code running in the Preview will not run as expected (e.g. #23225).

    The Customizer preview intercepts all click events and sends the intended URL to the parent window so that the Customizer can initiate the request to refresh the preview. The only way to change the current page in the preview is by clicking a standard links with a URL; any form submissions in the preview are completely disabled, resulting in the search results page not being reachable from within the preview (#20714). Any navigation system that uses JavaScript to change the window’s location also will fail, for instance using a dropdown.

    The current unique method for refreshing the preview worked fine when the Customizer was limited to a handful of settings. But now as more and more of WordPress is being added to the Customizer, and now that themes are increasingly leveraging JavaScript, we need a more robust approach to implementing the Customizer which will solve the above challenges and provide new opportunities.

    Customizer Transactions

    The proposal is that we introduce persisted Customizer settings, in other words “Customizer transactions”. Here’s how it may work:

    When opening the Customizer for the first time, a transaction UUID is generated. Whenever a setting changes, an Ajax request sends the updated setting to WordPress to be persisted in a wp_transaction post which has a post_name corresponding to that UUID (or such a transaction post is created on the fly if not existing already). Any changes made in the Customizer then get amended to the same wp_transaction post, which has a key/value JSON blob as its post_content.

    When a user hits the Save & Publish button, the underlying wp_transaction post gets a post status change to publish. When transitioning into this status, each of the settings in the transaction at that point get saved to the database—they get committed.

    Instead of using an Ajax POST to send the customized settings to the preview, we then only have to reference the transaction UUID when loading URLs into the Customizer preview. What this means is that we no longer have to use a blank iframe but can load the window with the natural URL for what is being previewed (#30028), but just with the transaction UUID query parameter tacked on.

    When this transaction UUID query parameter is present, filters get added to amend all URLs generated in the preview to also include this UUID, so the transaction context is persisted as the user navigates around the site in the preview window. Forms also get this transaction UUID added as another input element, so any form submissions will also keep the preview inside the transaction. Additionally, WP Ajax requests are intercepted to tack on the transaction UUID so that now even Ajax requests can be previewed in the Customizer without any extra work.

    Now that the document in the preview window is actually at the URL being previewed (as opposed to about:blank), refreshing the preview is greatly simplified: instead of capturing scroll position, doing Ajax POST, writing the response with document.write(), and restoring the scroll position—now the preview window just has to do a simple location.reload(). JavaScript now runs in the expected context, and full JS applications can be previewed in the Customizer.

    As noted above, each time the Customizer is opened and a setting is updated the first time, a wp_transaction post is created with a draft status, and this post gets updated each time a setting is changed during that Customizer session. You also can open the Customizer as a whole (at customize.php) with this transaction UUID supplied and that settings in that existing transaction draft will be loaded. This means you can draft Customizer settings and return to them later, or make some changes and then send it along to another user to finalize (realtime collaboration would be possible as well with some heartbeat integration, or else a locking mechanism would make sense). The capability to publish wp_transaction posts could be restricted to an administrator role, with other roles being able to save posts with a pending status to submit for review.

    Also as noted above, the point at which the settings in a transaction get saved (committed) to the database is when the wp_transaction post transitions to a publish status. This being the case it naturally allows for transaction posts to be scheduled to apply in the future. If you want to make a bunch of changes to your site appear at midnight on Saturday, you could go in on Friday and add/remove widgets, change background images, and do anything else the Customizer allows and then have this transaction be scheduled for the desired time. When it publishes, all of the settings would go live on the site. This resolves #28721.

    With each Customizer session resulting in a new transaction post being created, then there is automatically a Customizer revision history (see #31089). Every transaction that has a publish post status is a change that went live on the site.

    Another side benefit to reworking the Customizer preview to load via a natural URL with the transaction UUID supplied is that there aren’t any intrinsic capabilities needed to preview a transaction on the site. A setting change gets authorized at the time of the change, and the sanitized setting is then persisted in the transaction post. The preview then just applies the pre-authorized and pre-sanitized settings. The interesting side-effect of this is that it means Customizer previews (frontend URLs with the transaction UUID amended) can be shared with anonymous users to review. You can pop open the URL in the preview iframe into a new window and share it with any user for review, and they don’t need the capability to customize.

    Lastly, something else that motivated my investigation into Customizer transactions is thinking about how the Customizer will relate to the upcoming REST API. How can the REST API be improved with the Customizer? Where do they intersect? If the REST API provides a transactions endpoint for doing CRUD operations on Customizer settings, and if the REST API also has global recognition for a customize_transaction_uuid query parameter in all requests, then it becomes possible for the Customizer to be used to preview changes in applications that merely interact with the JSON REST API, as long as they include the transaction UUID in the requests.

    Partial Refresh

    There’s one drawback I’ve encountered when implementing a patch for what I’ve described above. As noted above, when a setting has a refresh transport, the preview window now does a regular location.reload(). When this happens, there is a momentary “flash of unloaded content” (white screen) which currently doesn’t happen when document.write() is employed to refresh the preview window. I’m not sure why this is, other than maybe document.write() initiates a synchronous DOM operation, whereas doing location.reload() initiates an asynchronous one. I’ve tried doing output buffering as well, to try to make sure the response gets sent all at once. But I haven’t had success. This is the current refresh behavior:

    If no solution can be found for the white-screen-flash-during-reload issue, there is an alternative (besides the postMessage transport) which would provide an even better experience than even now with the “seamless” full page refresh: partial refresh (#27355).

    When a setting change can’t be previewed purely with JavaScript (via postMessage), or it doesn’t make sense to re-implement all of the PHP logic in JS (which is not DRY), the Customizer currently necessitates a full refresh of the entire page. With the proposed partial refresh transport, however, only the container element(s) in which the setting appears in the preview would get fetched from the server via Ajax and inserted into the DOM. This is much faster than having to refresh the entire page, and it retains the overall document state (e.g. whether the sidebar is expanded or not).

    There are challenges for implementing partial refresh in a way that it can be enabled by default, however. When implementing partial refresh support for widgets in the Widget Customizer feature-as-plugin for 3.9, I found that themes had to explicitly opt-in to partial-refreshed widgets because a widget could be inside a sidebar that has a dynamic layout (e.g. jQuery Masonry) or the widget may have JS-driven functionality that has to be re-initialized when updated partial is injected. So partial refresh for widgets was removed from being included in WordPress 3.9, but the functionality has recently been resurrected in the Customize Partial Refresh plugin. More research is needed into how much partial refresh we can have enabled by default, and where we need explicit opt-in.

    Call for Feedback

    So there’s a lot of exciting possibilities introduced with Customizer transactions. I’d love to hear what you think. I have an working patch written and it exists in a pull request on GitHub. I welcome comments there on the PR. Naturally, the changes would need to be split up into smaller patches for committing to SVN.

    Related tickets:

    • #30937: Add Customizer transactions (main ticket)
    • #30028: Load Customizer preview iframe with natural URL
    • #30936: Dynamically create WP_Customize_Settings for settings created on JS client
    • #27355: Customizer: Add framework for partial preview refreshes
    • #20714: Theme customizer: Impossible to preview a search results page
    • #23225: Customizer is Incompatible with jQuery UI Tabs.
    • #28721: Scheduled changes for the customizer
    • #31089: Customizer revisions
    • #31517: Customizer: show a notice after attempting to navigate to external links in live previews

    Appendix: Why not just use MySQL transactions?

    Something interesting to investigate for the future would if we could take this another (lower) level and actually use MySQL transactions for the Customizer. This would make the Customizer much easier to extend beyond options and theme mods, as the Customizer could just start a MySQL transaction and when a setting is changed, just keep a log of any INSERT/UPDATE/DELETE statement performed during a MySQL transaction. They can then be re-played whenever the preview reloads, and then followed by a COMMIT when the Customizer is saved. These SQL statements can be saved in the wp_transaction post, as opposed to the JSON blob containing the key/value settings data. Or the use of MySQL transactions could go deeper and the SAVEPOINT could be utilized to store the transaction natively in MySQL.

    But there are some concerns about using MySQL transactions: first, there’s the question of compatibility and whether MySQL transactions would be available on the wide array of hosting environments where WordPress runs, and what MySQL storage engines are used. Then there’s the question of how conflicts would be resolved when the auto-incremented IDs in the transaction diverge from those outside. And also there’s the concern of storing SQL statements the wp_transaction post’s post_content, and how this might introduce vulnerabilities. Lastly, if we use MySQL transactions as opposed to storing the staged settings in a wp_transaction post, then we’d miss out on being able to inspect the contents of a transaction to see what changes are contained within it.

    In any case, using MySQL transactions would be an interesting alternative to the current WP_Customize_Setting abstraction.

    • nvartolomei 12:47 pm on January 26, 2015 Permalink | Log in to Reply

      Huh, nice writeup.

      The idea of transmitting UUID via URL looks kinda scary to me, so many places to keep this in head, and again looks like a crappy hack.

      Isn’t a better way to store this uuid along with user session data?

      • Weston Ruter 6:59 pm on January 26, 2015 Permalink | Log in to Reply

        Initially I was thinking of using a cookie to store which transaction that is currently open. But I realized that using a cookie (or usermeta) would not work because a user could have multiple Customizer sessions open in different windows, with a different transaction in each of them: there can be multiple Customizer sessions for a given user session. A query parameter was the only way to implement this, that I could find.

        Besides, using the UUID query var has the nice benefit of being able to share frontend URLs including the UUID query var with non-authenticated users to review what changes the transaction would apply.

    • PeterRKnight 8:28 pm on January 27, 2015 Permalink | Log in to Reply

      I like the idea of revision history and perhaps even the ability to save settings as a per-theme profile of sorts (makes a ton of sense in my book). I do think part of the problem as described can be dealt with more simply by using localstorage to store settings during a customizer session.

      Partial refresh could perhaps be tackled by letting widget developers have the ability to explicitly opt-out (rather than opt-in) and force a reload instead, as well as being able to globally filter the refresh method. This way plugins/themes can force fallback behaviour if they have javascript logic running that would not work properly otherwise. I might be underestimating the amount of widgets that have the kind of js logic that wouldn’t work properly in the partial refresh scenario though.

      Themes that use ajax techniques share this problem though. Right now WordPress doesn’t offer any help with developers making their scripts function robustly when, say, their widget is inserted dynamically, or when page content containing a shortcode that has javascript logic. For one of my own plugins I use node insertion detection to load/initialize scripts on demand. This can be achieved with Mutation observer or detection through css animation events. There is also a need I think for a clientside asset loader a-la require.js that compliments the existing scripts and styles api on the php side of things.

      • Weston Ruter 10:54 pm on January 27, 2015 Permalink | Log in to Reply

        localStorage could be used to prevent losing settings upon leaving the Customizer, but that’s about it. It would still require doing a POST request for each load of the preview since the data wouldn’t be stored in the database to reference otherwise, so you would miss out on the many advantages gained by just referencing a transaction via a query param, as I tried to detail above.

        Regarding partial refresh, I like the idea of adopting an opt-out approach as opposed to opt-in, however the value of doing this would have to be carefully evaluated in light of the Core principle of backwards-compatibility.

        Regarding Ajax, my patch automatically handles ensuring that Ajax requests get evaluated in the context of the current transaction. This is done simply by using a jQuery.ajaxPrefilter to inject the transaction UUID into the URL being requested. If the Customizer’s settings weren’t stored in a transaction on the server and referenceable by UUID, then this would not be possible, or it would be complicated by having to force the method to POST and then include the transaction’s data encoded as JSON in $_POST['customized']. This may not work, however, because the Ajax handler could be explicitly expecting a GET request. I think overall it is messier.

  • K.Adam White 7:58 pm on November 13, 2013 Permalink
    Tags: , javascript, JSHint   

    Finding and Fixing JavaScript errors with JSHint 

    The JavaScript Coding Standards have been updated, so it’s time to move on to tackling our JSHint errors!

    JSHint is a tool to check for errors in JavaScript code. As was discussed last week, we’re kicking off a small effort to work through our core JavaScript files. To get through the errors revealed by JSHint as quickly as possible, we’re following the model established by the Inline Docs team and posting a list of files with issues so that people can “claim” the files they’d like to fix!

    At the bottom is a list of every file in core that is displaying JSHint errors. Files with a checkmark have been patched and should now be passing lint. Files marked with (@username #xxxxx) are already claimed, and being worked on.

    Please read and understand the process we’ll be following to address these issues! Many thanks to @azaozz, @nacin and @jorbin for helping identify the safest way to approach fixing these errors, and to @rzen for posting the Inline Docs article on which we based this guide.

    How to contribute:

    1. Leave a comment on this post with the file* you’re about to edit (check the list first to make sure it hasn’t already been claimed).
    2. Update your local WordPress SVN to the latest version of WordPress trunk (currently 3.8-alpha).
    3. Create a new ticket on Trac for the file.
      JSHint-related trac ticket settings

      • Format the title as “jshint shouldn’t throw errors – path/to/file.js”.
      • Assign the ticket to the “Build Tools” component.
      • Make sure your email is stored in Trac’s preferences

      If you are logged in, you can click this link to automatically open a ticket with the right settings.

    4. Edit the file, and make a patch. Please make sure you create the patch from the root directory of your WordPress SVN checkout. If you are working on a large file, consider making multiple patches for each type of change.
    5. Upload your patch to the Trac ticket you created, and add the keyword “has-patch”.

    *Note: We strongly encourage you to work on one file at a time. These shouldn’t take very long, but if you call a bunch at once and get tied up, we won’t be able to get through these as quickly as possible. To quote @rzen from the inline docs effort, “your edits should be made and patched swiftly so that they aren’t invalidated by (or don’t invalidate) another patch.”

    Keeping Discussions Focused:

    Any discussion about the specifics of a patch itself should happen on Trac. Discussion about the overall effort should take place during our standing weekly meeting, on Wednesdays at 1900 UTC in #wordpress-dev*.

    Files needing patches:

    Checked files are now passing JSHint

    See all open tickets in the Build Tools component

    For tips on dealing with global variables, inlined third-party code within first-party scripts, etc, see the JSHint tips in the JavaScript Coding Standards

    For the curious, this list was created with a jazzy little command @nacin came up with to pipe Grunt output through ack:

    grunt jshint --force | ack '^Linting src/' | ack -o 'wp-.*.js' | sort | uniq -c | sort

    What we’re NOT doing

    The two JSHint options called out in the earlier post, “curly” and “eqeqeq,” would ordinarily make up the vast majority of the errors JSHint reports in our files. We’ve currently set Grunt and JSHint to ignore these two types of errors when JSHint is run against core. While these are best practices, we’ll come back to them once we address the more significant code smell issues like undefined variables.

    Also note that we’re not tackling whitespace or non-JSHint-related refactoring during this effort. We’ll get there, but we have to mitigate the risk to core as much as possible so we don’t interrupt the 3.8 cycle. Keep your changes focused on passing JSHint this go-around.

  • K.Adam White 9:48 pm on November 5, 2013 Permalink
    Tags: , javascript   

    JavaScript Coding Standards 

    The PHP files in WordPress core become cleaner and easier to read with every release, thanks in part to our standards for PHP code style. Our JavaScript, on the other hand, hasn’t gotten nearly enough love. This post is intended to open up the recent discussion around JavaScript style to the greater community so we can make up for lost time.

    Don’t we already have a style guide for JavaScript?

    Back in March, @tommcfarlin added a set of coding standards for JavaScript to the developer handbook. These WordPress JS coding standards are a great work-in-progress, but weren’t fully comprehensive (leading to some comment threads clarifying various areas). More importantly, without any clear implementation plan the style guide failed to gain traction.

    At WordCamp Boston’s core contributor day I revisited this style guide with @mattwiebe and Corey Frang (@gnarf37). It is important to identify *and implement* conventions for JS style ASAP because syntax issues in the JS within WordPress may hide latent bugs, and inconsistent code discourages contribution. Focusing on implementation lead us to look for an existing, proven JS style guide with a .jshintrc file (a set of configuration options for the JSHint code quality tool) which we could adopt largely as-is: Getting JSHint in place lets us see the biggest issues in our JS, so we can begin tackling them incrementally (perhaps in the same manner as the inline docs effort).

    After looking at Idiomatic.js and several other widely-adopted JS style guides, we feel the jQuery Foundation’s jQuery Core JavaScript Style Guide guide is the closest match for what we need in WordPress.

    Adopting the jQuery Core JavaScript Style Guide

    jQuery’s guide shared WordPress core’s love of white space—the same “when in doubt, space it out” mantra from the existing JS style page. Moreover, jQuery’s code conventions have been referenced in trac tickets as an example of how we should be writing our code. Adopting their guide wholesale capitalizes on our stylistic similarities, and will let us adopt their .jshintrc and any future code quality tools they write with minimal changes.
    (More …)

    • Pbearne 9:55 pm on November 5, 2013 Permalink | Log in to Reply

      I will be happy do a bit of this.

    • deltafactory 9:57 pm on November 5, 2013 Permalink | Log in to Reply

      I’ve been thinking about threequals and curly-braces since Boston. It’s hard to break the habit.

      I’d like to help with the cleanup effort. It would benefit me to familiarize myself with more of the JS bits of WordPress.

    • Mike Bijon 9:58 pm on November 5, 2013 Permalink | Log in to Reply

      After reading the summary in email, my only concern was jQuery’s use of double-quotes vs. ours … seeing the longer article, that’s handled and I can’t think of any reasons to object.

      On the + side, adopting jQuery’s standards wholesale should reduce maintenance & debate. Plus, getting started sooner than later to *any* standard should help speed JS work & maybe help a few overly-debated JS tickets in Trac.

      Looking forward to seeing the sprint schedules

    • adamsilverstein 10:27 pm on November 5, 2013 Permalink | Log in to Reply

      Great post, thanks! I will try to make the meeting tomorrow and assist in the cleanup effort.

    • Matt Wiebe 10:46 pm on November 5, 2013 Permalink | Log in to Reply

      I have another (virtual) meeting at the same time, but I should be able to chime in.

      Thanks for pushing this forwards @kadamwhite 🙂

    • ericsherred 10:59 pm on November 5, 2013 Permalink | Log in to Reply

      Sounds like fun to me.

    • Dion Hulse 12:07 am on November 6, 2013 Permalink | Log in to Reply

      Wouldn’t it be better for us to standardise on for ( var i = 0; i < 100; i++ ) { instead of including var outside of the iterator? IIRC, including it outside was for some rather old browsers that we no longer (and probably haven’t for a long time) supported.

      • Andrew Ozz 1:12 am on November 6, 2013 Permalink | Log in to Reply

        As far as I remember defining all vars at the beginning of the scope mimics the actual way the script is parsed. Don’t think defining vars in the middle or end was a problem in any browser.

        • Dion Hulse 1:19 am on November 6, 2013 Permalink | Log in to Reply

          I thought I’d heard a rumour of an early IE bug.. but you’re probably right, defining it earlier is most likely only a parsing optimization, something we probably don’t need to worry about.

        • Tom McFarlin 1:52 am on November 6, 2013 Permalink | Log in to Reply

          +1 to this.

          Including all var declarations at the beginning of the function is how the script is parsed, and for those who are fans of JSLint, you’ll notice that combining all var declarations together is preferred[0].


        • K.Adam White 2:14 am on November 6, 2013 Permalink | Log in to Reply

          As Tom notes, Andrew is correct—Variable declarations are “hoisted” to the top of the function’s scope, so declaring all your variables first is a best practice (it unifies the code’s visual structure with how it is parsed by the JS engine). There’s actually a “onevar” parameter in JSHint to enforce this style.

      • WraithKenny 2:10 am on November 6, 2013 Permalink | Log in to Reply

        I think it’s better, considering `for ( i = 0; i < 100; i++ ) { … } … var i = 2; alert( i );` would be confusing ('100') because of hoisting.

    • Andrew Ozz 1:47 am on November 6, 2013 Permalink | Log in to Reply

      Re-reading jQuery Core JavaScript Style Guide again: apart from the single/double quotes, other differences are the lack of indentation for `case` in `switch` and the hard limit to 100 characters per line (counting tabs as 4 chars). All of the rest more or less match our PHP and current JS coding standards. We also (used to?) have few more, like the strong discouragement of using nested ternary operators.

      So the question is: should we adopt the jQuery standard “wholesale” and depart from our PHP coding standard or should we continue to keep our PHP and JS coding standards as close as possible?

      • Tom McFarlin 1:58 am on November 6, 2013 Permalink | Log in to Reply

        I’m for the adoption of jQuery standards as much as possible; however, I do err on the side of keeping the JavaScript closely-related to our PHP coding standards (which is what I tried to do with the first draft of the standards).

        The reason being is that I don’t think we, as developers, should have to maintain two different set of standards.

        When working on client-side code, I often find myself thinking What’s the server-side standard for this, again? and then I try to apply that.

        Because I – and I’m sure most of us – are so familiar with the PHP standards, perhaps we should implement a “when it doubt, default to PHP standards.”

      • K.Adam White 2:26 am on November 6, 2013 Permalink | Log in to Reply

        I’m of a case-by-case mind on this. For example, I’ve encountered very few situations where >100 characters in a line were truly needed (and not just a symptom of hard-to-read or overly-nested code), so I’d be inclined to keep that. On the flip side, I’m all for keeping indentation rules consistent with PHP.

        Thanks for raising these questions, this is exactly what we need! Both here and during tomorrow’s chat I hope to identify any other differences between our PHP style and the proposed guide, and make decisions about which way to go. We’ve already identified a few areas in which we want to go a different way than jQuery. It’s a useful set of default behaviors, but what style guide we adopt isn’t what’s important—what is important is that consistency.

        • Andrew Ozz 2:47 am on November 6, 2013 Permalink | Log in to Reply

          Yes, the “around 80, max 100 chars” limit might eventually surface when something has many levels of indentation (5 – 6 tabs). This is not so hard to hit with longer jQuery chains which should probably be broken on multiple lines. Thinking it may be nice to have it as a rule in the PHP coding standard too, just not sure if it needs to be enforced.

    • Tom McFarlin 2:02 am on November 6, 2013 Permalink | Log in to Reply

      I’m going to try to make it to the meeting – what server and channel will the meeting take place?

      • K.Adam White 2:12 am on November 6, 2013 Permalink | Log in to Reply

        Good point, that’s something people need to know: Freenode, right in #wordpress-dev. (Note: That time was selected because I was not aware of any conflicting meetings; If anybody has a meeting in #wordpress-dev scheduled at that time, please let us know and we’ll get another room!)

    • Paul Clark 4:09 am on November 6, 2013 Permalink | Log in to Reply

      Count me in for a JSHint sprint!

    • Gary Jones 9:22 am on November 6, 2013 Permalink | Log in to Reply

      Not sure I can make it tonight, so I’m leaving my thoughts here that hopefully someone can take into consideration during the meeting.

      General adoption of the jQuery standards: +1
      Two exceptions to those standards: +1

      Would like to see a push towards named rather than anonymous functions = more self-documenting code, fewer nested levels -> avoid hitting line limits, reduce complexity.

      Consider use of ‘es3’ option in .jshintrc, since WP still needs to support IE8-9, and that will catch use of reserved words being used as properties with dot notation etc.

      I’m up for helping out with some JS tidying.

    • K.Adam White 1:00 am on November 10, 2013 Permalink | Log in to Reply

      Just a heads-up for everybody waiting for an update on this: Hang tight for a day or two, I’m working with @kpdesign to get the JS Standards handbook page updated and up to our standards.

    • Lance Willett 3:36 am on November 12, 2013 Permalink | Log in to Reply

      Thanks for your work on this—more vigorous standards and cleaner code FTW.

  • Aaron Jorbin 9:10 pm on September 13, 2013 Permalink
    Tags: javascript,   

    JavaScript Unit Tests for Core 

    Recently WordPress added QUnit as a JavaScript unit testing framework and added its first JavaScript unit tests. I thought I would walk through how to run the tests and how to write tests so that we can increase our JavaScript test coverage. All of these are based upon using the develop.svn.wordpress.org checkout which is where the JS unit tests live.
    (More …)

    • Ryan McCue 1:37 am on September 14, 2013 Permalink | Log in to Reply

      For anyone who’s wondering what the hell is going on on Windows: You have to run grunt via the Windows command line, and you cannot run it via Cygwin. If you do run it via Cygwin, you’ll see random inexplicable errors and missing output. It’s pretty annoying (in fact, it stops me from using Grunt), but you can’t really do anything about it.

    • adamsilverstein 6:17 pm on September 14, 2013 Permalink | Log in to Reply

      Great post, thanks for keeping this moving!

    • K.Adam White 5:50 pm on September 16, 2013 Permalink | Log in to Reply

      For those on Windows, the “msys” shell that installs as “Git Bash” when you download the official Windows build of Git should work fine once you install the Windows build of Node.

  • Andrew Nacin 5:36 pm on August 15, 2013 Permalink
    Tags: , javascript   

    JavaScript meeting on Monday. @koop @azaozz @carldanley @adamsilverstein @kadamwhite will be meeting on Monday at 9 p.m. EDT (Tuesday, August 20 at 01:00 GMT) in the #wordpress-dev IRC channel. I’ll let them build out an agenda in the comments, but here’s some potential topics I know they’ve been kicking around:

    • JS style, structure, and design patterns, and what new code should look like
    • JS unit testing, including candidate frameworks and where to start
    • APIs, such as WP-style hooks (actions/filters), what form they should take if they should exist
    • Which areas of our JS need refactoring and overhauls, and what that might look like
    • Which JS-heavy features need eventual iteration (often “version 2”)
    • What action items could be done for WP 3.7 and 3.8
    • Beau Lebens 5:54 pm on August 15, 2013 Permalink | Log in to Reply

      I’ll try to be there.

    • Marko Heijnen 6:41 pm on August 15, 2013 Permalink | Log in to Reply

      I would love to join but unsure yet. The time to me is wrong choosen.

    • adamsilverstein 12:27 am on August 17, 2013 Permalink | Log in to Reply

      I am looking forward to contributing to the JS effort in 3.7 and will be at the meeting!

    • raam86 12:34 am on August 18, 2013 Permalink | Log in to Reply

      I would be delighted to help in anyway possible.

    • Andrew Ozz 5:31 pm on August 19, 2013 Permalink | Log in to Reply

      One more item for the agenda: upgrade TinyMCE to 4.x (3.7 or 3.8)?. Will break many WordPress plugins that add TinyMCE 3.x plugins (JS errors are silenced so TinyMCE would continue to work but without the 3.x plugin). All custom plugins need a rewrite, including ours.

      There are tons of improvements in TinyMCE 4.x:

      And a lot more both in the UI and back-end.

      • Aaron D. Campbell 5:45 pm on August 19, 2013 Permalink | Log in to Reply

        I’m really interested in this one. I’d be happy to help wherever. I’d love to see it in 3.7, but that’s mostly selfish. The current TinyMCE is the biggest struggle for many of our clients, and while 4.x isn’t perfect it DOES seem to be a serious improvement.

      • WraithKenny 6:16 pm on August 21, 2013 Permalink | Log in to Reply

        I’d like to see it upgraded to 4.x for 3.7 (or for 3.8 if 3.7 is not doable).

    • Josh (Ult. Tinymce) 6:33 pm on August 21, 2013 Permalink | Log in to Reply

      Hi, I am the developer of Ultimate Tinymce. I would LOVE to help out with this, and be included in the development.

      As Andrew mentioned, a ton of plugins (and themes) are going to need to be re-written to handle the new Tinymce 4.x interface. (Andrew… much respect!!)

      I was wondering if someone could point me in the direction of learning how to use the “#wordpress-dev IRC channel”, so that I may also be present in the meeting.

  • Andrew Nacin 11:09 pm on August 29, 2012 Permalink
    Tags: , javascript   

    External Libraries in 3.5 

    We work hard to keep our external libraries as up-to-date as possible with each major release. Here’s what you can find today in trunk, all of which are the latest version:

    Edit: jQuery 1.8.1 (due out this week) and jQuery UI 1.9 (due out next week) are now both in trunk.

    And, Backbone.js 0.9.2 and Underscore.js 1.3.3 were both added to core last week.

    If you’re a plugin developer using a bundled library, we strongly suggest you follow their development as well, to ensure code you write will be compatible in the future. The projects we have adopted have very similar backwards compatibility policies as ours (which would be strive to always be compatible), which make this pretty easy to do.

    Additionally, Prototype and script.aculo.us have been removed from core. They are still registered; enqueueing them will pull from ajax.googleapis.com. This is only being done for backwards compatibility and doesn’t indicate a change in policy. It was just a lot of bloat to keep shipping when core hasn’t used either for four years. (Both were updated to the latest versions in the process, something we can/may continue to do.)

    See also the conversion to .min.js from .dev.js.

    • Alex Mills (Viper007Bond) 11:14 pm on August 29, 2012 Permalink | Log in to Reply

      Nice way to do backwards compatibility without having to ship the files. Well done.

    • Emil Uzelac 11:18 pm on August 29, 2012 Permalink | Log in to Reply

      Very cool 🙂

    • Japh 12:31 am on August 30, 2012 Permalink | Log in to Reply

      Great work! Nice to see us dropping scripts we’re no longer using and adding new ones.

      I assume we’ll be going with Backbone 0.9.2 and Underscore 1.3.3 (really just adding here for future reference)

    • ckhicks 6:04 am on August 30, 2012 Permalink | Log in to Reply

      I’m really excited about this. Excluding the older libraries is a big step, but I’m glad to see the weight lessened on that front. Keep up the great work!

    • Marcus 3:18 pm on August 30, 2012 Permalink | Log in to Reply

      Good to hear!

      If you’re a plugin developer using a bundled library, we strongly suggest you follow their development as well, to ensure code you write will be compatible in the future.

      And theme developers too! A scary number of plugins and themes alike are still bundling jQuery and the UI, or using outdated versions on the Google CDN.

      Ironically Japh and i had a chat about this earlier 🙂

  • Andrew Nacin 11:08 pm on August 29, 2012 Permalink
    Tags: , javascript   

    Minified versus development scripts and .min.js 

    For some time (since r10291), WordPress has shipped minified scripts and styles as .js and .css, with the non-minified, “development” versions at .dev.js and .dev.css.

    These weren’t great for discoverability and it has become clear that these are non-standard. So, we’ve moved to using .min.js and .min.css for minified files. You can now find the “development” versions at .js and .css. This also works nicely with tools like ack, which are coded to ignore .min.js.

    This was implemented in #21633. Now if only we can get TinyMCE to move away from _src.js. 🙂

    A note, for some external libraries, we don’t include the un-minified versions. In this case, you can find them on their respective websites and also in the sources repository. (This is linked from wordpress.org, which in turn is referenced at the bottom of our license file.) @scribu and I were talking about writing a developer plugin to use un-minified versions of these libraries, which would be cool.

    More on external libraries in 3.5 here.

  • Ryan Boren 6:45 pm on March 27, 2009 Permalink
    Tags: , javascript   

    Image header cropping now uses Jcrop. 

    Image header cropping now uses Jcrop.

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Skip to toolbar