Read about our upcoming Code of Conduct on this issue

Commit ebca9417 authored by Leon Arnott's avatar Leon Arnott
Browse files

Fixed, in a somewhat forceful fashion, bugs where (button:) links (plus a lot...

Fixed, in a somewhat forceful fashion, bugs where (button:) links (plus a lot of other block elements) would be forced into inline flow during some transitions, due to <tw-transition-container> being given 'display:inline-block'.

This COULD cause some issues with some other transitioning elements (not to mention custom story structures), but it seems to be working as intended at present.

Also:

 * Fixed the border of (input-box:) elements, such that (border:) can alter it correctly.
 * Made it so that various 3.2.0 commands that should not have changers attached will now correctly error when that happens.
 * Fixed the sizing of "button" links in (dialog:) dialogs.
parent 056aaa92979c
...@@ -70,6 +70,7 @@ Documentation is at http://twine2.neocities.org/. See below for compilation inst ...@@ -70,6 +70,7 @@ Documentation is at http://twine2.neocities.org/. See below for compilation inst
* The `(text-style:)` styles "rumble" and "shudder" no longer need to set `display:inline-block` on the hook. * The `(text-style:)` styles "rumble" and "shudder" no longer need to set `display:inline-block` on the hook.
* The shadow of the `(text-style:)` style "emboss" has been slightly adjusted. * The shadow of the `(text-style:)` style "emboss" has been slightly adjusted.
* Now, attaching `(transition:)` to a passage link instead of `(transition-depart:)` or `(transition-arrive:)` will cause an error instead of doing nothing. * Now, attaching `(transition:)` to a passage link instead of `(transition-depart:)` or `(transition-arrive:)` will cause an error instead of doing nothing.
* Now, when Harlowe detects that a hook containing block elements is being transitioned, the `<tw-transition-container>` element will be given `display:block`. This is to fix a number of transition animation bugs, though it may cause certain structures to animate differently during transition.
* `(mouseover:)`, `(mouseout:)` and their related macros, which use mouse-hovering input that isn't possible on touch devices, will now fall back to simply being activated by clicks/touches on touch devices. * `(mouseover:)`, `(mouseout:)` and their related macros, which use mouse-hovering input that isn't possible on touch devices, will now fall back to simply being activated by clicks/touches on touch devices.
* After much fretting and fussing, I've decided to un-deprecate `(subarray:)` and `(substring:)`, because my intended subsequence syntax - `$a's 1stTo2ndlast` and `$a's (range: $b, $c)` - has a not-uncommon edge case where it fails - when `$c` in the preceding example is negative - and I've abandoned plans to alter it to accommodate this case. This un-deprecation changes nothing about how they behaved, but the documentation has been rewritten to include them. * After much fretting and fussing, I've decided to un-deprecate `(subarray:)` and `(substring:)`, because my intended subsequence syntax - `$a's 1stTo2ndlast` and `$a's (range: $b, $c)` - has a not-uncommon edge case where it fails - when `$c` in the preceding example is negative - and I've abandoned plans to alter it to accommodate this case. This un-deprecation changes nothing about how they behaved, but the documentation has been rewritten to include them.
* Slightly adjusted the animation of `(text-style:"rumble")` and `(text-style:"shudder")` so that the text shifts position from its centre, rather than its left edge. * Slightly adjusted the animation of `(text-style:"rumble")` and `(text-style:"shudder")` so that the text shifts position from its centre, rather than its left edge.
......
...@@ -1925,7 +1925,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -1925,7 +1925,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
/* /*
The <textarea> is created with its height directly feeding into its rows value. The <textarea> is created with its height directly feeding into its rows value.
*/ */
let source = '<textarea style="margin-left:' + marginLeft + "%;width:" + size + '%" rows=' + height + '>' let source = '<textarea style="width:100%" rows=' + height + '>'
/* /*
HTML-escape the passed-in text, which is apparently all that's necessary. HTML-escape the passed-in text, which is apparently all that's necessary.
(force-input-box:)es, of course, start with no text inside. (force-input-box:)es, of course, start with no text inside.
...@@ -1962,10 +1962,23 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -1962,10 +1962,23 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
return true; return true;
}; };
} }
/* cd.styles.push({
Like (box:), this needs display:block so that it can take up an entire row. /*
*/ Like (box:), this needs display:block so that it can take up an entire row.
cd.styles.push({ display: 'block' }); */
display: 'block',
/*
These need to be on the <tw-enchantment> so that the resulting border is one that (border:) can correctly replace.
*/
'margin-left': marginLeft + "%",
width: size + '%',
/*
The default border style can be overridden with (border:).
*/
'border-style'() {
return this.style.borderStyle || 'solid';
},
});
return assign(cd, { source, append: "replace", }); return assign(cd, { source, append: "replace", });
}, },
[either(VarBind, String), optional(either(positiveInteger,String)), optional(either(positiveInteger,String)), optional(String)]) [either(VarBind, String), optional(either(positiveInteger,String)), optional(either(positiveInteger,String)), optional(String)])
...@@ -1980,7 +1993,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -1980,7 +1993,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
``` ```
|fan)[The overhead fan spins lazily.] |fan)[The overhead fan spins lazily.]
(link:"Turn on fan")[(show:?fan)] (link:"Turn on fan")[(t8n:"dissolve")(show:?fan)]
``` ```
Rationale: Rationale:
...@@ -2027,6 +2040,9 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2027,6 +2040,9 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
(show:) will reveal every hook with the given name. To only reveal a specific hook, you can use the (show:) will reveal every hook with the given name. To only reveal a specific hook, you can use the
possessive syntax, as usual: `(show: ?shrub's 1st)`. possessive syntax, as usual: `(show: ?shrub's 1st)`.
You can attach a transition changer, such as (transition:), (transition-time:), (transition-delay:), and the rest, to this command.
Doing so will cause that transition to be applied to the hook.
Much like (replace:), (show:) cannot affects hooks or text that haven't been printed yet - if the (show:) Much like (replace:), (show:) cannot affects hooks or text that haven't been printed yet - if the (show:)
runs at the same time that the passage is appearing (as in, it isn't inside a hook that's delayed by (live:), (link:), (event:) runs at the same time that the passage is appearing (as in, it isn't inside a hook that's delayed by (live:), (link:), (event:)
or similar macros), and a hook or line of text appears after it in the passage, the macro won't replace its contents or similar macros), and a hook or line of text appears after it in the passage, the macro won't replace its contents
...@@ -2054,7 +2070,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2054,7 +2070,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
Example usage: Example usage:
``` ```
|1>[You drew a (either:...(range:2,10), "Jack", "Queen", "King", "Ace") of (either:"Hearts","Clubs","Spades","Diamonds").] |1>[You drew a (either:...(range:2,10), "Jack", "Queen", "King", "Ace") of (either:"Hearts","Clubs","Spades","Diamonds").]
(link-rerun:"Shuffle and draw.")[(rerun:?1)] (link-rerun:"Shuffle and draw.")[(t8n:"dissolve")(rerun:?1)]
``` ```
Rationale: Rationale:
...@@ -2082,6 +2098,9 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2082,6 +2098,9 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
(rerun:) will re-run every hook with the given name. To only re-run a specific hook, you can use the (rerun:) will re-run every hook with the given name. To only re-run a specific hook, you can use the
possessive syntax, as usual: `(rerun: ?daydream's 1st)`. possessive syntax, as usual: `(rerun: ?daydream's 1st)`.
You can attach a transition changer, such as (transition:), (transition-time:), (transition-delay:), and the rest, to this command.
Doing so will cause that transition to be applied to the hook.
(rerun:), unlike (show:), will not work on hidden hooks until they become visible using (show:) or (link-show:). (rerun:), unlike (show:), will not work on hidden hooks until they become visible using (show:) or (link-show:).
If you want to rerun a hook multiple times based on elapsed real time, use the (live:) macro. If you want to rerun a hook multiple times based on elapsed real time, use the (live:) macro.
...@@ -2169,6 +2188,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2169,6 +2188,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
If you want to remove the hook's contents all together, and re-create it anew later, consider using (replace:) and (rerun:) If you want to remove the hook's contents all together, and re-create it anew later, consider using (replace:) and (rerun:)
rather than (show:) and (hide:). rather than (show:) and (hide:).
This command can't have changers attached - attempting to do so will produce an error.
See also: See also:
(show:), (rerun:), (replace:) (show:), (rerun:), (replace:)
...@@ -2177,8 +2198,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2177,8 +2198,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
*/ */
("hide", ("hide",
noop, noop,
(cd, section, ...hooks) => { (section, ...hooks) => {
hooks.forEach(hook => hook.forEach(section, elem => { hooks.forEach(hook => hook.forEach(section, elem => {
/* /*
The test for whether a hook has been shown is, simply, whether it has "hidden" data. The test for whether a hook has been shown is, simply, whether it has "hidden" data.
...@@ -2196,9 +2216,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2196,9 +2216,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
*/ */
elem.data('hidden', elem.contents().detach()); elem.data('hidden', elem.contents().detach());
})); }));
return cd;
}, },
[rest(HookSet)]) [rest(HookSet)], false /* Can't have attachments.*/)
/*d: /*d:
(stop:) -> Command (stop:) -> Command
...@@ -2316,7 +2335,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2316,7 +2335,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
} }
requestAnimationFrame(Engine.showPassage.bind(Engine, State.passage, false /* stretchtext value */)); requestAnimationFrame(Engine.showPassage.bind(Engine, State.passage, false /* stretchtext value */));
}, },
[String], false) [String], false /* Can't have attachments.*/)
/*d: /*d:
(mock-visits: ...String) -> Command (mock-visits: ...String) -> Command
...@@ -2354,6 +2373,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2354,6 +2373,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
If you undo past a passage that used (mock-visits:), the effects of that macro call will be removed, as if it had been a (set:) macro call. If you undo past a passage that used (mock-visits:), the effects of that macro call will be removed, as if it had been a (set:) macro call.
This command can't have changers attached - attempting to do so will produce an error.
See also: See also:
(history:), (set:) (history:), (set:)
...@@ -2371,8 +2392,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2371,8 +2392,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
return TwineError.create('datatype', "I can't mock-visit '" + incorrect + "' because no passage with that name exists."); return TwineError.create('datatype', "I can't mock-visit '" + incorrect + "' because no passage with that name exists.");
} }
}, },
(cd, _, ...names) => { State.mockVisits = clone(names); }, (_, ...names) => { State.mockVisits = clone(names); },
[rest(String)]) [rest(String)], false /* Can't have attachments.*/)
/*d: /*d:
(dialog: [Bind], String, ...String) -> Command (dialog: [Bind], String, ...String) -> Command
...@@ -2412,6 +2433,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine', ...@@ -2412,6 +2433,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
From version 3.2.0 on, it is possible to attach changers to this command. `(t8n:'slide-up')+(text-rotate-x:25)(dialog:"EMAIL SENT!")`, for instance, produces a dialog From version 3.2.0 on, it is possible to attach changers to this command. `(t8n:'slide-up')+(text-rotate-x:25)(dialog:"EMAIL SENT!")`, for instance, produces a dialog
that's tilted upward, and which slides upward when it appears. that's tilted upward, and which slides upward when it appears.
You can customise the dialog by attaching changers to this command. Attaching a (transition:) command will cause the dialog to appear using that transition.
See also: See also:
(cycling-link:), (prompt:), (confirm:) (cycling-link:), (prompt:), (confirm:)
......
...@@ -528,6 +528,16 @@ define(['jquery', 'markup', 'utils/polyfills'], ...@@ -528,6 +528,16 @@ define(['jquery', 'markup', 'utils/polyfills'],
*/ */
el.css('display','inline' + (el.children().length ? '-block' : '')); el.css('display','inline' + (el.children().length ? '-block' : ''));
} }
else {
/*
Both of these are necessary for overriding "display:inline-block" for certain transitions,
including those that use transform.
*/
el.css({
display:'block !important',
width:"100%",
});
}
/* /*
Each frame, reduce the delay, and potentially reduce it further if this Each frame, reduce the delay, and potentially reduce it further if this
transition can be skipped and an input is being held. transition can be skipped and an input is being held.
...@@ -585,6 +595,16 @@ define(['jquery', 'markup', 'utils/polyfills'], ...@@ -585,6 +595,16 @@ define(['jquery', 'markup', 'utils/polyfills'],
*/ */
el.css('display','inline' + (el.children().length ? '-block' : '')); el.css('display','inline' + (el.children().length ? '-block' : ''));
} }
else {
/*
Both of these are necessary for overriding "display:inline-block" for certain transitions,
including those that use transform.
*/
el.css({
display:'block !important',
width:"100%",
});
}
onTransitionComplete(el, transitionTime + transitionDelay - expedite, transitionSkip, (elapsedRealTime) => { onTransitionComplete(el, transitionTime + transitionDelay - expedite, transitionSkip, (elapsedRealTime) => {
/* /*
Unwrap the wrapping... unless it contains a non-unwrappable element, Unwrap the wrapping... unless it contains a non-unwrappable element,
......
...@@ -19,8 +19,8 @@ define(['jquery', 'utils', 'renderer'], function($, Utils, Renderer) { ...@@ -19,8 +19,8 @@ define(['jquery', 'utils', 'renderer'], function($, Utils, Renderer) {
causes a second "Cancel" link to appear next to "OK". causes a second "Cancel" link to appear next to "OK".
*/ */
+ (buttons.length + (buttons.length
? buttons.reduce((code, {name}, i) => code + "<span style='margin:0 " ? buttons.reduce((code, {name}, i) => code + "<tw-link style='margin:0 "
+ (i === 0 ? "0.5em 0 0" : i === buttons.length-1 ? "0 0 0.5em" : '0.5em') + "'><tw-link tabindex=0>" + name + "</tw-link></span>", '') + (i === buttons.length-1 ? "0 0 0.5em" : i === 0 ? "0.5em 0 0" : '0.5em') + "' tabindex=0>" + name + "</tw-link>", '')
: "<tw-link tabindex=0>" + buttons[0].name + "</tw-link>" : "<tw-link tabindex=0>" + buttons[0].name + "</tw-link>"
) )
+ "</tw-dialog-links></tw-dialog></tw-backdrop>"); + "</tw-dialog-links></tw-dialog></tw-backdrop>");
......
...@@ -139,10 +139,14 @@ tw-link.enchantment-button, ...@@ -139,10 +139,14 @@ tw-link.enchantment-button,
/* /*
...and links inside (dialog:) dialogs. ...and links inside (dialog:) dialogs.
*/ */
tw-dialog-links tw-link { tw-dialog-links {
border-radius: 16px; padding-top:1.5em;
border-style: solid; tw-link {
border-width: 2px; border-radius: 16px;
text-align:center; border-style: solid;
display:block; border-width: 2px;
} text-align:center;
display:inline-block;
padding:0px 8px;
}
}
\ No newline at end of file
...@@ -109,8 +109,7 @@ tw-story { ...@@ -109,8 +109,7 @@ tw-story {
background-color: transparent; background-color: transparent;
font:inherit; font:inherit;
color:inherit; color:inherit;
border-color:inherit; border-style:none;
border-style:solid;
padding: 2px; padding: 2px;
} }
......
...@@ -391,16 +391,16 @@ describe("interface macros", function(){ ...@@ -391,16 +391,16 @@ describe("interface macros", function(){
var code = a[0], marginLeft=a[1], width=a[2], height=a[3]; var code = a[0], marginLeft=a[1], width=a[2], height=a[3];
var t = runPassage("("+name+":'" + code + "', " + height + ",'Foo')[]").find('textarea'); var t = runPassage("("+name+":'" + code + "', " + height + ",'Foo')[]").find('textarea');
var s = t.attr('style'); var p = t.parent().attr('style');
expect(s).toMatch(RegExp("margin-left:\\s*"+marginLeft+"%")); expect(p).toMatch(RegExp("margin-left:\\s*"+marginLeft+"%"));
expect(s).toMatch(RegExp("\\bwidth:\\s*"+width+"%")); expect(p).toMatch(RegExp("\\bwidth:\\s*"+width+"%"));
if (!height) { if (!height) {
expect(t.attr('rows')).not.toBe(height+''); expect(t.attr('rows')).not.toBe(height+'');
} }
else { else {
expect(t.attr('rows')).toBe(height+''); expect(t.attr('rows')).toBe(height+'');
} }
expect(t.parent().attr('style')).toMatch(/display:\s*block/); expect(p).toMatch(/display:\s*block/);
}); });
}); });
if (!force) { if (!force) {
......
...@@ -193,13 +193,15 @@ describe("save macros", function() { ...@@ -193,13 +193,15 @@ describe("save macros", function() {
runPassage("quatro", "quatro"); runPassage("quatro", "quatro");
deletePassage('dos'); deletePassage('dos');
var p = runPassage("(loadgame:'1')"); var p = runPassage("(loadgame:'1')");
expect($("tw-story").find("tw-backdrop > tw-dialog").length).toBe(1);
expect($("tw-dialog").find('tw-link').first().text()).toBe("Yes");
expect($("tw-dialog").find('tw-link').last().text()).toBe("No");
$("tw-dialog").find('tw-link').first().click();
setTimeout(function() { setTimeout(function() {
expect($("tw-story").find("tw-backdrop > tw-dialog").length).toBe(0); expect($("tw-story").find("tw-backdrop > tw-dialog").length).toBe(1);
done(); expect($("tw-dialog").find('tw-link').first().text()).toBe("Yes");
expect($("tw-dialog").find('tw-link').last().text()).toBe("No");
$("tw-dialog").find('tw-link').first().click();
setTimeout(function() {
expect($("tw-story").find("tw-backdrop > tw-dialog").length).toBe(0);
done();
},120);
},120); },120);
//TODO: Test that the save data is actually deleted. //TODO: Test that the save data is actually deleted.
}); });
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment