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
* 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.
* 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.
* 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.
......
......@@ -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.
*/
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.
(force-input-box:)es, of course, start with no text inside.
......@@ -1962,10 +1962,23 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
return true;
};
}
/*
Like (box:), this needs display:block so that it can take up an entire row.
*/
cd.styles.push({ display: 'block' });
cd.styles.push({
/*
Like (box:), this needs display:block so that it can take up an entire row.
*/
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", });
},
[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',
```
|fan)[The overhead fan spins lazily.]
(link:"Turn on fan")[(show:?fan)]
(link:"Turn on fan")[(t8n:"dissolve")(show:?fan)]
```
Rationale:
......@@ -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
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:)
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
......@@ -2054,7 +2070,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
Example usage:
```
|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:
......@@ -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
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:).
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',
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:).
This command can't have changers attached - attempting to do so will produce an error.
See also:
(show:), (rerun:), (replace:)
......@@ -2177,8 +2198,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
*/
("hide",
noop,
(cd, section, ...hooks) => {
(section, ...hooks) => {
hooks.forEach(hook => hook.forEach(section, elem => {
/*
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',
*/
elem.data('hidden', elem.contents().detach());
}));
return cd;
},
[rest(HookSet)])
[rest(HookSet)], false /* Can't have attachments.*/)
/*d:
(stop:) -> Command
......@@ -2316,7 +2335,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
}
requestAnimationFrame(Engine.showPassage.bind(Engine, State.passage, false /* stretchtext value */));
},
[String], false)
[String], false /* Can't have attachments.*/)
/*d:
(mock-visits: ...String) -> Command
......@@ -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.
This command can't have changers attached - attempting to do so will produce an error.
See also:
(history:), (set:)
......@@ -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.");
}
},
(cd, _, ...names) => { State.mockVisits = clone(names); },
[rest(String)])
(_, ...names) => { State.mockVisits = clone(names); },
[rest(String)], false /* Can't have attachments.*/)
/*d:
(dialog: [Bind], String, ...String) -> Command
......@@ -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
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:
(cycling-link:), (prompt:), (confirm:)
......
......@@ -528,6 +528,16 @@ define(['jquery', 'markup', 'utils/polyfills'],
*/
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
transition can be skipped and an input is being held.
......@@ -585,6 +595,16 @@ define(['jquery', 'markup', 'utils/polyfills'],
*/
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) => {
/*
Unwrap the wrapping... unless it contains a non-unwrappable element,
......
......@@ -19,8 +19,8 @@ define(['jquery', 'utils', 'renderer'], function($, Utils, Renderer) {
causes a second "Cancel" link to appear next to "OK".
*/
+ (buttons.length
? buttons.reduce((code, {name}, i) => code + "<span 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>", '')
? buttons.reduce((code, {name}, i) => code + "<tw-link style='margin:0 "
+ (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-dialog-links></tw-dialog></tw-backdrop>");
......
......@@ -139,10 +139,14 @@ tw-link.enchantment-button,
/*
...and links inside (dialog:) dialogs.
*/
tw-dialog-links tw-link {
border-radius: 16px;
border-style: solid;
border-width: 2px;
text-align:center;
display:block;
}
tw-dialog-links {
padding-top:1.5em;
tw-link {
border-radius: 16px;
border-style: solid;
border-width: 2px;
text-align:center;
display:inline-block;
padding:0px 8px;
}
}
\ No newline at end of file
......@@ -109,8 +109,7 @@ tw-story {
background-color: transparent;
font:inherit;
color:inherit;
border-color:inherit;
border-style:solid;
border-style:none;
padding: 2px;
}
......
......@@ -391,16 +391,16 @@ describe("interface macros", function(){
var code = a[0], marginLeft=a[1], width=a[2], height=a[3];
var t = runPassage("("+name+":'" + code + "', " + height + ",'Foo')[]").find('textarea');
var s = t.attr('style');
expect(s).toMatch(RegExp("margin-left:\\s*"+marginLeft+"%"));
expect(s).toMatch(RegExp("\\bwidth:\\s*"+width+"%"));
var p = t.parent().attr('style');
expect(p).toMatch(RegExp("margin-left:\\s*"+marginLeft+"%"));
expect(p).toMatch(RegExp("\\bwidth:\\s*"+width+"%"));
if (!height) {
expect(t.attr('rows')).not.toBe(height+'');
}
else {
expect(t.attr('rows')).toBe(height+'');
}
expect(t.parent().attr('style')).toMatch(/display:\s*block/);
expect(p).toMatch(/display:\s*block/);
});
});
if (!force) {
......
......@@ -193,13 +193,15 @@ describe("save macros", function() {
runPassage("quatro", "quatro");
deletePassage('dos');
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() {
expect($("tw-story").find("tw-backdrop > tw-dialog").length).toBe(0);
done();
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() {
expect($("tw-story").find("tw-backdrop > tw-dialog").length).toBe(0);
done();
},120);
},120);
//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