Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

Commit

Permalink
Per November 2015 TC39 meeting, renaming to padStart/padEnd, and …
Browse files Browse the repository at this point in the history
…bumping to stage 3.
  • Loading branch information
ljharb committed Nov 17, 2015
1 parent fd0ec3a commit 35f1ef6
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 36 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# [String.prototype.padLeft](https://github.com/es-shims/String.prototype.padLeft) / [String.prototype.padRight](https://github.com/es-shims/String.prototype.padRight)
Proposal, specs, tests, and reference implementation for String.prototype.padLeft/padRight.
# [String.prototype.padStart](https://github.com/es-shims/String.prototype.padStart) / [String.prototype.padEnd](https://github.com/es-shims/String.prototype.padEnd)
Proposal, specs, tests, and reference implementation for String.prototype.padStart/padEnd.

This [initial](http://wiki.ecmascript.org/doku.php?id=strawman:string_padding) proposal was drafted by [@KevinGrandon](https://github.com/kevingrandon) with input from [@rwaldron](https://github.com/rwaldron) and [@dherman](https://github.com/dherman).
Updated spec drafted by [@ljharb](https://github.com/ljharb) with input from [@rwaldron](https://github.com/rwaldron), [@allenwb](https://github.com/allenwb), and [@dherman](https://github.com/dherman).
Expand All @@ -17,7 +17,8 @@ It is highly probable that the majority of current string padding implementation
You can view the spec in [markdown format](spec.md) or rendered as [HTML](http://tc39.github.io/proposal-string-pad-left-right/).

## Naming
For consistency with [trimLeft/trimRight](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), and `reduce`/`reduceRight`, despite the existence of `startsWith`/`endsWith`, we have settled on `padRight` and `padLeft`.
~~ For consistency with [trimStart/trimRight](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), and `reduce`/`reduceRight`, despite the existence of `startsWith`/`endsWith`, we have settled on `padLeft` and `padRight`. ~~
Update per November 2015 TC39 meeting: the names will change to `padStart` and `padEnd`, and the `trimLeft`/`trimRight` proposal should also add non-annex-B aliases `trimStart`/`trimEnd`.

## Semantics of "min length" vs "max length"
While updating this proposal with spec language, we discussed at length whether the first parameter should determine the minimum length or the maximum length of the padded string. Specifically, "min length" semantics says `'foo'.padRight(4, '12')` would output `foo12`, and "max length" semantics would output `foo1`. Since one of the primary use cases of `padLeft`/`padRight` is for formatting monospaced text in columns, and since "min length" semantics can be achieved via `String#repeat`, we decided that "max length" was the far more useful approach.
Expand Down
24 changes: 12 additions & 12 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="stylesheet" href="./spec.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">
<script src="./spec.js"></script>
<title>String.prototype.padLeft / padRight</title>
<script type="application/json" id="menu-search-biblio">{"clauses":{"String.prototype.padLeft":{"location":"","id":"String.prototype.padLeft","aoid":null,"title":"String.prototype.padLeft( maxLength [ , fillString ] )","number":"1"},"String.prototype.padRight":{"location":"","id":"String.prototype.padRight","aoid":null,"title":"String.prototype.padRight( maxLength [ , fillString ] )","number":"2"},"sec-copyright-and-software-license":{"location":"","id":"sec-copyright-and-software-license","aoid":null,"title":"Copyright & Software License","number":"A"}},"ops":{},"productions":{},"terms":{},"examples":{},"notes":{},"tables":{},"figures":{}}</script>
<title>String.prototype.padStart / padEnd</title>
<script type="application/json" id="menu-search-biblio">{"clauses":{"String.prototype.padStart":{"location":"","id":"String.prototype.padStart","aoid":null,"title":"String.prototype.padStart( maxLength [ , fillString ] )","number":"1"},"String.prototype.padEnd":{"location":"","id":"String.prototype.padEnd","aoid":null,"title":"String.prototype.padEnd( maxLength [ , fillString ] )","number":"2"},"sec-copyright-and-software-license":{"location":"","id":"sec-copyright-and-software-license","aoid":null,"title":"Copyright & Software License","number":"A"}},"ops":{},"productions":{},"terms":{},"examples":{},"notes":{},"tables":{},"figures":{}}</script>
</head>

<body>
Expand All @@ -18,17 +18,17 @@
</div>
<div id="menu-toc">
<ol class="toc">
<li><span class="item-toggle-none"></span><a href="#String.prototype.padLeft" title="String.prototype.padLeft( maxLength [ , fillString ] )"><span class="secnum">1</span> String.prototype.padLeft( maxLength [ , fillString ] )</a></li>
<li><span class="item-toggle-none"></span><a href="#String.prototype.padRight" title="String.prototype.padRight( maxLength [ , fillString ] )"><span class="secnum">2</span> String.prototype.padRight( maxLength [ , fillString ] )</a></li>
<li><span class="item-toggle-none"></span><a href="#String.prototype.padStart" title="String.prototype.padStart( maxLength [ , fillString ] )"><span class="secnum">1</span> String.prototype.padStart( maxLength [ , fillString ] )</a></li>
<li><span class="item-toggle-none"></span><a href="#String.prototype.padEnd" title="String.prototype.padEnd( maxLength [ , fillString ] )"><span class="secnum">2</span> String.prototype.padEnd( maxLength [ , fillString ] )</a></li>
<li><span class="item-toggle-none"></span><a href="#sec-copyright-and-software-license" title="Copyright &amp; Software License"><span class="secnum">A</span> Copyright &amp; Software License</a></li>
</ol>
</div>
</div>
<h1 class="version">Stage 1 Draft / November 3, 2015</h1>
<h1 class="title">String.prototype.padLeft / padRight</h1>
<emu-clause id="String.prototype.padLeft">
<h1><span class="secnum">1</span>String.prototype.padLeft( maxLength [ , fillString ] )<span class="utils"><span class="anchor"><a href="#String.prototype.padLeft">#</a></span></span></h1>
<p>When the <code>padLeft</code> method is called, the following steps are taken:</p>
<h1 class="version">Stage 3 Draft / November 17, 2015</h1>
<h1 class="title">String.prototype.padStart / padEnd</h1>
<emu-clause id="String.prototype.padStart">
<h1><span class="secnum">1</span>String.prototype.padStart( maxLength [ , fillString ] )<span class="utils"><span class="anchor"><a href="#String.prototype.padStart">#</a></span></span></h1>
<p>When the <code>padStart</code> method is called, the following steps are taken:</p>
<emu-alg>
<ol>
<li>Let <var>O</var> be ? <a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-requireobjectcoercible">RequireObjectCoercible</a>(
Expand All @@ -54,9 +54,9 @@ <h1><span class="secnum">1</span>String.prototype.padLeft( maxLength [ , fillStr

</emu-clause>

<emu-clause id="String.prototype.padRight">
<h1><span class="secnum">2</span>String.prototype.padRight( maxLength [ , fillString ] )<span class="utils"><span class="anchor"><a href="#String.prototype.padRight">#</a></span></span></h1>
<p>When the <code>padRight</code> method is called, the following steps are taken:</p>
<emu-clause id="String.prototype.padEnd">
<h1><span class="secnum">2</span>String.prototype.padEnd( maxLength [ , fillString ] )<span class="utils"><span class="anchor"><a href="#String.prototype.padEnd">#</a></span></span></h1>
<p>When the <code>padEnd</code> method is called, the following steps are taken:</p>
<emu-alg>
<ol>
<li>Let <var>O</var> be ? <a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-requireobjectcoercible">RequireObjectCoercible</a>(
Expand Down
14 changes: 9 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
{
"name": "ecma-proposal-string-pad-left-right",
"name": "ecma-proposal-string-pad-start-eng",
"version": "0.0.0",
"description": "ES7 spec proposal for String.prototype.{padLeft,padRight}",
"description": "ES7 spec proposal for String.prototype.{padStart,padEnd}",
"main": "index.js",
"scripts": {
"build": "ecmarkup spec.emu --js=spec.js --css=spec.css | js-beautify -f - --type=html -t > index.html",
"prepublish": "npm run build && echo >&2 'no publishing' && exit 255"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ljharb/proposal-string-pad-left-right.git"
"url": "git+https://github.com/ljharb/proposal-string-pad-start-end.git"
},
"keywords": [
"String.prototype.padLeft",
"String.prototype.padRight",
"String.prototype.padStart",
"String.prototype.padEnd",
"padLeft",
"padRight",
"padStart",
"padEnd",
"pad",
"padding",
"ES7",
Expand All @@ -24,9 +28,9 @@
"author": "Jordan Harband <ljharb@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/ljharb/proposal-string-pad-left-right/issues"
"url": "https://github.com/tc39/proposal-string-pad-start-end/issues"
},
"homepage": "https://github.com/ljharb/proposal-string-pad-left-right#readme",
"homepage": "https://github.com/tc39/proposal-string-pad-start-end#readme",
"dependencies": {},
"devDependencies": {
"ecmarkup": "^2.8.0",
Expand Down
8 changes: 4 additions & 4 deletions polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const ToLength = argument => {
return len;
};

if (!String.prototype.padLeft) {
String.prototype.padLeft = function padLeft(maxLength, fillString = ' ') {
if (!String.prototype.padStart) {
String.prototype.padStart = function padStart(maxLength, fillString = ' ') {
const O = RequireObjectCoercible(this);
const S = String(O);
const intMaxLength = ToLength(maxLength);
Expand All @@ -36,8 +36,8 @@ if (!String.prototype.padLeft) {
};
}

if (!String.prototype.padRight) {
String.prototype.padRight = function padRight(maxLength, fillString = ' ') {
if (!String.prototype.padEnd) {
String.prototype.padEnd = function padEnd(maxLength, fillString = ' ') {
const O = RequireObjectCoercible(this);
const S = String(O);
const intMaxLength = ToLength(maxLength);
Expand Down
16 changes: 8 additions & 8 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">
<script src="./spec.js"></script>
<pre class="metadata">
title: String.prototype.padLeft / padRight
stage: 1
title: String.prototype.padStart / padEnd
stage: 3
contributors: Jordan Harband
</pre>
<emu-clause id="String.prototype.padLeft">
<h1>String.prototype.padLeft( maxLength [ , fillString ] )</h1>
<p>When the `padLeft` method is called, the following steps are taken:</p>
<emu-clause id="String.prototype.padStart">
<h1>String.prototype.padStart( maxLength [ , fillString ] )</h1>
<p>When the `padStart` method is called, the following steps are taken:</p>
<emu-alg>
1. Let _O_ be ? RequireObjectCoercible(*this* value).
1. Let _S_ be ? ToString(_O_).
Expand All @@ -29,9 +29,9 @@ contributors: Jordan Harband

</emu-clause>

<emu-clause id="String.prototype.padRight">
<h1>String.prototype.padRight( maxLength [ , fillString ] )</h1>
<p>When the `padRight` method is called, the following steps are taken:</p>
<emu-clause id="String.prototype.padEnd">
<h1>String.prototype.padEnd( maxLength [ , fillString ] )</h1>
<p>When the `padEnd` method is called, the following steps are taken:</p>
<emu-alg>
1. Let _O_ be ? RequireObjectCoercible(*this* value).
1. Let _S_ be ? ToString(_O_).
Expand Down
8 changes: 4 additions & 4 deletions spec.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# String.prototype.padLeft( maxLength [ , fillString ] )
# String.prototype.padStart( maxLength [ , fillString ] )

When the _padLeft_ method is called, the following steps are taken:
When the _padStart_ method is called, the following steps are taken:
1. Let _O_ be ? RequireObjectCoercible(*this* value).
1. Let _S_ be ? ToString(_O_).
1. Let _intMaxLength_ be ? ToLength(_maxLength_).
Expand All @@ -16,9 +16,9 @@ When the _padLeft_ method is called, the following steps are taken:
Note: the first argument _maxLength_ will be clamped such that it can be no smaller than the length of the *this* value.
Note: The optional second argument _fillString_ defaults to *" "* (a string consisting of U+0020 SPACE).

# String.prototype.padRight( maxLength [ , fillString ] )
# String.prototype.padEnd( maxLength [ , fillString ] )

When the _padRight_ method is called, the following steps are taken:
When the _padEnd_ method is called, the following steps are taken:
1. Let _O_ be ? RequireObjectCoercible(*this* value).
1. Let _S_ be ? ToString(_O_).
1. Let _intMaxLength_ be ? ToLength(_maxLength_).
Expand Down

3 comments on commit 35f1ef6

@jdalton
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was still wishy-washy-could-be-interpreted-either-way. Seems kind of odd to go against the grain of the established de-facto (trimLeft/trimRight) and use start and end. Grumble grumble

@ljharb
Copy link
Member Author

@ljharb ljharb commented on 35f1ef6 Nov 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general consensus was that since trimLeft/trimRight were the only examples of "left" and "right", and they're Annex B/legacy anyways, we could fix this mistake now. In addition, the trimLeft/trimRight proposal will also now add trimStart/trimEnd, which is filed as tc39/proposal-string-left-right-trim#3

@jdalton
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trims have been around since ~2009 though.

Will trimStart and trimEnd be different than trimLeft and trimRight?

Just read up and trimStart and trimEnd are intended to be aliases (so no new functionality).
Won't that be confusing?

Please sign in to comment.