Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (190541 => 190542)
--- trunk/Source/_javascript_Core/ChangeLog 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-10-03 03:18:19 UTC (rev 190542)
@@ -1,3 +1,38 @@
+2015-10-02 Matt Baker <[email protected]>
+
+ Web Inspector: Add breakpoint option to ignore n times before stopping
+ https://bugs.webkit.org/show_bug.cgi?id=147664
+
+ Reviewed by Timothy Hatcher.
+
+ * debugger/Breakpoint.h:
+ (JSC::Breakpoint::Breakpoint):
+ Added ignoreCount and hitCount fields. Cleaned up initializers.
+
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::hasBreakpoint):
+ If a breakpoint matches the current text position, increment breakpoint hit count and
+ compare with ignore count before testing the breakpoint condition.
+
+ * inspector/ScriptBreakpoint.h:
+ (Inspector::ScriptBreakpoint::ScriptBreakpoint):
+ Added ignoreCount field. Cleaned up initializers.
+
+ * inspector/ScriptDebugServer.cpp:
+ (Inspector::ScriptDebugServer::setBreakpoint):
+ Added ignoreCount field.
+
+ * inspector/agents/InspectorDebuggerAgent.cpp:
+ (Inspector::buildObjectForBreakpointCookie):
+ (Inspector::InspectorDebuggerAgent::setBreakpointByUrl):
+ (Inspector::InspectorDebuggerAgent::setBreakpoint):
+ (Inspector::InspectorDebuggerAgent::continueToLocation):
+ (Inspector::InspectorDebuggerAgent::didParseSource):
+ Plumbing for ignoreCount property.
+
+ * inspector/protocol/Debugger.json:
+ Added optional ignoreCount property to BreakpointOptions object.
+
2015-10-02 Filip Pizlo <[email protected]> and Mark Lam <[email protected]>
We should not add InferredTypeTables to old Structures
Modified: trunk/Source/_javascript_Core/debugger/Breakpoint.h (190541 => 190542)
--- trunk/Source/_javascript_Core/debugger/Breakpoint.h 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/debugger/Breakpoint.h 2015-10-03 03:18:19 UTC (rev 190542)
@@ -35,21 +35,16 @@
struct Breakpoint : public DoublyLinkedListNode<Breakpoint> {
Breakpoint()
- : id(noBreakpointID)
- , sourceID(noSourceID)
- , line(0)
- , column(0)
- , autoContinue(false)
{
}
- Breakpoint(SourceID sourceID, unsigned line, unsigned column, const String& condition, bool autoContinue)
- : id(noBreakpointID)
- , sourceID(sourceID)
+ Breakpoint(SourceID sourceID, unsigned line, unsigned column, const String& condition, bool autoContinue, unsigned ignoreCount)
+ : sourceID(sourceID)
, line(line)
, column(column)
, condition(condition)
, autoContinue(autoContinue)
+ , ignoreCount(ignoreCount)
{
}
@@ -60,15 +55,19 @@
, column(other.column)
, condition(other.condition)
, autoContinue(other.autoContinue)
+ , ignoreCount(other.ignoreCount)
+ , hitCount(other.hitCount)
{
}
- BreakpointID id;
- SourceID sourceID;
- unsigned line;
- unsigned column;
+ BreakpointID id { noBreakpointID };
+ SourceID sourceID { noSourceID };
+ unsigned line { 0 };
+ unsigned column { 0 };
String condition;
- bool autoContinue;
+ bool autoContinue { false };
+ unsigned ignoreCount { 0 };
+ unsigned hitCount { 0 };
static const unsigned unspecifiedColumn = UINT_MAX;
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (190541 => 190542)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2015-10-03 03:18:19 UTC (rev 190542)
@@ -420,6 +420,10 @@
if (hitBreakpoint)
*hitBreakpoint = *breakpoint;
+ breakpoint->hitCount++;
+ if (breakpoint->ignoreCount >= breakpoint->hitCount)
+ return false;
+
if (breakpoint->condition.isEmpty())
return true;
Modified: trunk/Source/_javascript_Core/inspector/ScriptBreakpoint.h (190541 => 190542)
--- trunk/Source/_javascript_Core/inspector/ScriptBreakpoint.h 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/inspector/ScriptBreakpoint.h 2015-10-03 03:18:19 UTC (rev 190542)
@@ -62,28 +62,31 @@
{
}
- ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, bool autoContinue)
+ ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, bool autoContinue, unsigned ignoreCount)
: lineNumber(lineNumber)
, columnNumber(columnNumber)
, condition(condition)
, autoContinue(autoContinue)
+ , ignoreCount(ignoreCount)
{
}
- ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, BreakpointActions& actions, bool autoContinue)
+ ScriptBreakpoint(int lineNumber, int columnNumber, const String& condition, BreakpointActions& actions, bool autoContinue, unsigned ignoreCount)
: lineNumber(lineNumber)
, columnNumber(columnNumber)
, condition(condition)
, actions(actions)
, autoContinue(autoContinue)
+ , ignoreCount(ignoreCount)
{
}
- int lineNumber;
- int columnNumber;
+ int lineNumber { 0 };
+ int columnNumber { 0 };
String condition;
BreakpointActions actions;
- bool autoContinue;
+ bool autoContinue { false };
+ unsigned ignoreCount { 0 };
};
} // namespace Inspector
Modified: trunk/Source/_javascript_Core/inspector/ScriptDebugServer.cpp (190541 => 190542)
--- trunk/Source/_javascript_Core/inspector/ScriptDebugServer.cpp 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/inspector/ScriptDebugServer.cpp 2015-10-03 03:18:19 UTC (rev 190542)
@@ -61,7 +61,7 @@
if (!sourceID)
return JSC::noBreakpointID;
- JSC::Breakpoint breakpoint(sourceID, scriptBreakpoint.lineNumber, scriptBreakpoint.columnNumber, scriptBreakpoint.condition, scriptBreakpoint.autoContinue);
+ JSC::Breakpoint breakpoint(sourceID, scriptBreakpoint.lineNumber, scriptBreakpoint.columnNumber, scriptBreakpoint.condition, scriptBreakpoint.autoContinue, scriptBreakpoint.ignoreCount);
JSC::BreakpointID id = Debugger::setBreakpoint(breakpoint, *actualLineNumber, *actualColumnNumber);
if (id != JSC::noBreakpointID && !scriptBreakpoint.actions.isEmpty()) {
#ifndef NDEBUG
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (190541 => 190542)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2015-10-03 03:18:19 UTC (rev 190542)
@@ -187,7 +187,7 @@
breakProgram(DebuggerFrontendDispatcher::Reason::Assert, buildAssertPauseReason(message));
}
-static Ref<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<InspectorArray>& actions, bool isRegex, bool autoContinue)
+static Ref<InspectorObject> buildObjectForBreakpointCookie(const String& url, int lineNumber, int columnNumber, const String& condition, RefPtr<InspectorArray>& actions, bool isRegex, bool autoContinue, unsigned ignoreCount)
{
Ref<InspectorObject> breakpointObject = InspectorObject::create();
breakpointObject->setString(ASCIILiteral("url"), url);
@@ -196,6 +196,7 @@
breakpointObject->setString(ASCIILiteral("condition"), condition);
breakpointObject->setBoolean(ASCIILiteral("isRegex"), isRegex);
breakpointObject->setBoolean(ASCIILiteral("autoContinue"), autoContinue);
+ breakpointObject->setInteger(ASCIILiteral("ignoreCount"), ignoreCount);
if (actions)
breakpointObject->setArray(ASCIILiteral("actions"), actions);
@@ -298,20 +299,22 @@
String condition = emptyString();
bool autoContinue = false;
+ unsigned ignoreCount = 0;
RefPtr<InspectorArray> actions;
if (options) {
options->getString(ASCIILiteral("condition"), condition);
options->getBoolean(ASCIILiteral("autoContinue"), autoContinue);
options->getArray(ASCIILiteral("actions"), actions);
+ options->getInteger(ASCIILiteral("ignoreCount"), ignoreCount);
}
BreakpointActions breakpointActions;
if (!breakpointActionsFromProtocol(errorString, actions, &breakpointActions))
return;
- m_javaScriptBreakpoints.set(breakpointIdentifier, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, actions, isRegex, autoContinue));
+ m_javaScriptBreakpoints.set(breakpointIdentifier, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, actions, isRegex, autoContinue, ignoreCount));
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue, ignoreCount);
for (ScriptsMap::iterator it = m_scripts.begin(); it != m_scripts.end(); ++it) {
String scriptURL = !it->value.sourceURL.isEmpty() ? it->value.sourceURL : it->value.url;
if (!matches(scriptURL, url, isRegex))
@@ -349,11 +352,13 @@
String condition = emptyString();
bool autoContinue = false;
+ unsigned ignoreCount = 0;
RefPtr<InspectorArray> actions;
if (options) {
options->getString(ASCIILiteral("condition"), condition);
options->getBoolean(ASCIILiteral("autoContinue"), autoContinue);
options->getArray(ASCIILiteral("actions"), actions);
+ options->getInteger(ASCIILiteral("ignoreCount"), ignoreCount);
}
BreakpointActions breakpointActions;
@@ -366,7 +371,7 @@
return;
}
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition, breakpointActions, autoContinue, ignoreCount);
actualLocation = resolveBreakpoint(breakpointIdentifier, sourceID, breakpoint);
if (!actualLocation) {
errorString = ASCIILiteral("Could not resolve breakpoint");
@@ -404,7 +409,7 @@
if (!parseLocation(errorString, location, sourceID, lineNumber, columnNumber))
return;
- ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", false);
+ ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", false, 0);
m_continueToLocationBreakpointID = scriptDebugServer().setBreakpoint(sourceID, breakpoint, &lineNumber, &columnNumber);
resume(errorString);
}
@@ -639,6 +644,7 @@
breakpointObject->getInteger(ASCIILiteral("columnNumber"), breakpoint.columnNumber);
breakpointObject->getString(ASCIILiteral("condition"), breakpoint.condition);
breakpointObject->getBoolean(ASCIILiteral("autoContinue"), breakpoint.autoContinue);
+ breakpointObject->getInteger(ASCIILiteral("ignoreCount"), breakpoint.ignoreCount);
ErrorString errorString;
RefPtr<InspectorArray> actions;
breakpointObject->getArray(ASCIILiteral("actions"), actions);
Modified: trunk/Source/_javascript_Core/inspector/protocol/Debugger.json (190541 => 190542)
--- trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2015-10-03 03:18:19 UTC (rev 190542)
@@ -48,7 +48,8 @@
"properties": [
{ "name": "condition", "type": "string", "optional": true, "description": "_expression_ to use as a breakpoint condition. When specified, debugger will only stop on the breakpoint if this _expression_ evaluates to true." },
{ "name": "actions", "type": "array", "optional": true, "items": { "$ref": "BreakpointAction" }, "description": "Actions to perform automatically when the breakpoint is triggered." },
- { "name": "autoContinue", "type": "boolean", "optional": true, "description": "Automatically continue after hitting this breakpoint and running actions." }
+ { "name": "autoContinue", "type": "boolean", "optional": true, "description": "Automatically continue after hitting this breakpoint and running actions." },
+ { "name": "ignoreCount", "type": "integer", "optional": true, "description": "Number of times to ignore this breakpoint, before stopping on the breakpoint and running actions." }
],
"description": "Extra options that modify breakpoint behavior."
},
Modified: trunk/Source/WebInspectorUI/ChangeLog (190541 => 190542)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-10-03 03:18:19 UTC (rev 190542)
@@ -1,5 +1,39 @@
2015-10-02 Matt Baker <[email protected]>
+ Web Inspector: Add breakpoint option to ignore n times before stopping
+ https://bugs.webkit.org/show_bug.cgi?id=147664
+
+ Reviewed by Timothy Hatcher.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ New strings for breakpoint popover labels.
+
+ * UserInterface/Controllers/BreakpointPopoverController.js:
+ (WebInspector.BreakpointPopoverController.prototype._createPopoverContent):
+ Add ignoreCount UI to popover, if backend support exists. UI based on same
+ feature in Xcode's breakpoint editing dialog.
+ (WebInspector.BreakpointPopoverController.prototype._popoverIgnoreInputChanged):
+ User input sanity checks on numeric input.
+
+ * UserInterface/Controllers/DebuggerManager.js:
+ Listen for changes to breakpoint ignoreCount property.
+
+ * UserInterface/Models/Breakpoint.js:
+ (WebInspector.Breakpoint):
+ (WebInspector.Breakpoint.prototype.get ignoreCount):
+ (WebInspector.Breakpoint.prototype.set ignoreCount):
+ New property for ignoreCount.
+ (WebInspector.Breakpoint.prototype.get options):
+ Added ignoreCount to options object.
+ (WebInspector.Breakpoint.prototype.get info):
+ Added ignoreCount to info object.
+
+ * UserInterface/Views/BreakpointPopoverController.css:
+ (#edit-breakpoint-popover-ignore):
+ New styles for breakpoint popover.
+
+2015-10-02 Matt Baker <[email protected]>
+
Web Inspector: Cleanup DebuggerManager, reduce `delete` and use Maps instead of objects
https://bugs.webkit.org/show_bug.cgi?id=149760
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (190541 => 190542)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2015-10-03 03:18:19 UTC (rev 190542)
@@ -315,6 +315,7 @@
localizedStrings["Icon and Text (Horizontal)"] = "Icon and Text (Horizontal)";
localizedStrings["Icon and Text (Vertical)"] = "Icon and Text (Vertical)";
localizedStrings["Identity"] = "Identity";
+localizedStrings["Ignore"] = "Ignore";
localizedStrings["Ignored"] = "Ignored";
localizedStrings["Image"] = "Image";
localizedStrings["Image Size"] = "Image Size";
@@ -635,5 +636,6 @@
localizedStrings["key"] = "key";
localizedStrings["line "] = "line ";
localizedStrings["originally %s"] = "originally %s";
+localizedStrings["times before stopping"] = "times before stopping";
localizedStrings["value"] = "value";
localizedStrings[" %s Profile Recorded"] = " %s Profile Recorded";
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js (190541 => 190542)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js 2015-10-03 03:18:19 UTC (rev 190542)
@@ -144,6 +144,27 @@
// COMPATIBILITY (iOS 7): Debugger.setBreakpoint did not support options.
if (DebuggerAgent.setBreakpoint.supports("options")) {
+ // COMPATIBILITY (iOS 9): Legacy backends don't support breakpoint ignore count. Since support
+ // can't be tested directly, check for CSS.getSupportedSystemFontFamilyNames.
+ // FIXME: Use explicit version checking once https://webkit.org/b/148680 is fixed.
+ if (CSSAgent.getSupportedSystemFontFamilyNames) {
+ let ignoreCountRow = table.appendChild(document.createElement("tr"));
+ let ignoreCountHeader = ignoreCountRow.appendChild(document.createElement("th"));
+ let ignoreCountLabel = ignoreCountHeader.appendChild(document.createElement("label"));
+ let ignoreCountData = ignoreCountRow.appendChild(document.createElement("td"));
+ this._ignoreCountInput = ignoreCountData.appendChild(document.createElement("input"));
+ this._ignoreCountInput.id = "edit-breakpoint-popover-ignore";
+ this._ignoreCountInput.type = "number";
+ this._ignoreCountInput.min = 0;
+ this._ignoreCountInput.value = this._ignoreCount || 0;
+ this._ignoreCountInput.addEventListener("change", this._popoverIgnoreInputChanged.bind(this));
+
+ let ignoreCountText = ignoreCountData.appendChild(document.createElement("span"));
+ ignoreCountLabel.setAttribute("for", this._ignoreCountInput.id);
+ ignoreCountLabel.textContent = WebInspector.UIString("Ignore");
+ ignoreCountText.textContent = WebInspector.UIString("times before stopping");
+ }
+
let actionRow = table.appendChild(document.createElement("tr"));
let actionHeader = actionRow.appendChild(document.createElement("th"));
let actionData = this._actionsContainer = actionRow.appendChild(document.createElement("td"));
@@ -191,6 +212,19 @@
this._breakpoint.condition = event.target.value;
}
+ _popoverIgnoreInputChanged(event)
+ {
+ let ignoreCount = 0;
+ if (event.target.value) {
+ ignoreCount = parseInt(event.target.value, 10);
+ if (isNaN(ignoreCount) || ignoreCount < 0)
+ ignoreCount = 0;
+ }
+
+ this._ignoreCountInput.value = ignoreCount;
+ this._breakpoint.ignoreCount = ignoreCount;
+ }
+
_popoverToggleAutoContinueCheckboxChanged(event)
{
this._breakpoint.autoContinue = event.target.checked;
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js (190541 => 190542)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js 2015-10-03 03:18:19 UTC (rev 190542)
@@ -35,6 +35,7 @@
WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.DisplayLocationDidChange, this._breakpointDisplayLocationDidChange, this);
WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.DisabledStateDidChange, this._breakpointDisabledStateDidChange, this);
WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.ConditionDidChange, this._breakpointEditablePropertyDidChange, this);
+ WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.IgnoreCountDidChange, this._breakpointEditablePropertyDidChange, this);
WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.AutoContinueDidChange, this._breakpointEditablePropertyDidChange, this);
WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.ActionsDidChange, this._breakpointEditablePropertyDidChange, this);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js (190541 => 190542)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js 2015-10-03 03:18:19 UTC (rev 190542)
@@ -39,6 +39,7 @@
var lineNumber = sourceCodeLocationOrInfo.lineNumber || 0;
var columnNumber = sourceCodeLocationOrInfo.columnNumber || 0;
var location = new WebInspector.SourceCodeLocation(null, lineNumber, columnNumber);
+ var ignoreCount = sourceCodeLocationOrInfo.ignoreCount || 0;
var autoContinue = sourceCodeLocationOrInfo.autoContinue || false;
var actions = sourceCodeLocationOrInfo.actions || [];
for (var i = 0; i < actions.length; ++i)
@@ -53,6 +54,7 @@
this._scriptIdentifier = scriptIdentifier || null;
this._disabled = disabled || false;
this._condition = condition || "";
+ this._ignoreCount = ignoreCount || 0;
this._autoContinue = autoContinue || false;
this._actions = actions || [];
this._resolved = false;
@@ -141,6 +143,25 @@
this.dispatchEventToListeners(WebInspector.Breakpoint.Event.ConditionDidChange);
}
+ get ignoreCount()
+ {
+ return this._ignoreCount;
+ }
+
+ set ignoreCount(ignoreCount)
+ {
+ console.assert(ignoreCount >= 0, "Ignore count cannot be negative.");
+ if (ignoreCount < 0)
+ return;
+
+ if (this._ignoreCount === ignoreCount)
+ return;
+
+ this._ignoreCount = ignoreCount;
+
+ this.dispatchEventToListeners(WebInspector.Breakpoint.Event.IgnoreCountDidChange);
+ }
+
get autoContinue()
{
return this._autoContinue;
@@ -165,6 +186,7 @@
{
return {
condition: this._condition,
+ ignoreCount: this._ignoreCount,
actions: this._serializableActions(),
autoContinue: this._autoContinue
};
@@ -179,6 +201,7 @@
columnNumber: this._sourceCodeLocation.columnNumber,
disabled: this._disabled,
condition: this._condition,
+ ignoreCount: this._ignoreCount,
actions: this._serializableActions(),
autoContinue: this._autoContinue
};
@@ -325,6 +348,7 @@
DisabledStateDidChange: "breakpoint-disabled-state-did-change",
ResolvedStateDidChange: "breakpoint-resolved-state-did-change",
ConditionDidChange: "breakpoint-condition-did-change",
+ IgnoreCountDidChange: "breakpoint-ignore-count-did-change",
ActionsDidChange: "breakpoint-actions-did-change",
AutoContinueDidChange: "breakpoint-auto-continue-did-change",
LocationDidChange: "breakpoint-location-did-change",
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointPopoverController.css (190541 => 190542)
--- trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointPopoverController.css 2015-10-03 03:10:13 UTC (rev 190541)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointPopoverController.css 2015-10-03 03:18:19 UTC (rev 190542)
@@ -60,6 +60,11 @@
width: 100%;
}
+#edit-breakpoint-popover-ignore {
+ width: 40px;
+ margin-right: 4px;
+}
+
#edit-breakpoint-popoover-auto-continue {
margin-left: 0;
margin-right: 4px;