Commit graph

682 commits

Author SHA1 Message Date
Thiemo Kreuz cfecfbc099 Fix remaining bottleneck in wikitext syntax highlighter
I was wondering why the performance when editing wikitext is
still so bad, and profiled it again. Turns out
StringStream.match() is still the bottleneck (even if already
100 times better than before Icbb1122).

The method is called with many different patterns from
mode/mediawiki/mediawiki.js. I profiled them individually and
found a single outlier. The idea is the same as in Icbb1122.
A pattern that is able to find something *in* a string is
doing nothing but wasting time, as StringStream.match() ignores
every result that is not at the start of the string.

The change adds the missing ^ anchor and wraps the regex pattern
from mw.config.get( 'wgUrlProtocols' ) (that is something like
"ftp:\/\/|http:\/\/|https:\/\/|…") in (?:…), which is a
non-matching group. This is necessary because of the | in the
pattern. The result is a pattern that looks like /^(?:…|…|…)/i.

I remember looking at this code while working on Icbb1122, but
didn't include it in the patch, and then forgot about it.

Bug: T270237
Bug: T270317
Change-Id: Iea2fd116b68704c3186b0edf965006cc7c6eda82
2021-02-05 16:07:40 +01:00
Adam Wight 81bd2fe546 Clean-up: inline array merge
Change-Id: Ie976bf70f4117db09b53e6192f983930c7e6a458
2021-02-01 13:24:05 +01:00
libraryupgrader 37b851824d build: Updating dependencies
composer:
* mediawiki/mediawiki-codesniffer: 34.0.0 → 35.0.0
* mediawiki/minus-x: 1.1.0 → 1.1.1

npm:
* eslint-config-wikimedia: 0.17.0 → 0.18.1

Change-Id: I9e4ed7d632072b303d0dcb4135a5ecaaf4b68685
2021-01-29 06:50:49 +00:00
jenkins-bot 96b81c3420 Merge "Log user edit count bucket" 2021-01-27 09:11:17 +00:00
Adam Wight 36212a7877 Log user edit count bucket
Bug: T269986
Change-Id: Iff3c983a59738312bc39bf65e2428526724fe139
2021-01-27 09:03:28 +00:00
Thiemo Kreuz 6bc81ffd50 Improve matchbrackets performance when moving the cursor
My previous patch Icbb1122 focused on the behavior of the
matchbrackets addon when the text is *edited*. This patch here
is about moving the cursor without changing the text. I
realized the addon re-draws everything every time the cursor
moves, even if the highlighted pair of brackets is still the
same. This triggers very expensive code in the CodeMirror lib.

I had a look at this expensive code, but did not found an easy
win. It just is what it is: an expensive re-draw. Instead I
introduced a caching layer that remembers the positions of the
previously highlighted brackets and bails out as early as
possible when nothing changed.

The biggest chunk of code is that "did something change?"
comparison. It looks expensive, but typically isn't. There are
typically only 2 elements in the array for a single
opening–closing pair. (Possibly more when there are multiple
text selections.) The elements in the two arrays are typically
in the same order. (Except the cursor is on the closing
bracket.) Which means the nested `every` → `for` loop will
typically be executed 2 times only – one time for each of the
2 elements.

I won't upload this change upstream because it is only relevant
together with our custom "in the middle" bracket highlighting.
With our customization we have many, many situations where the
highlighted brackets don't change. This (almost) doesn't happen
upstream.

Bug: T270317
Change-Id: I789b45362388f0818e797f789f6af427a35e3e06
2021-01-27 08:54:32 +00:00
Thiemo Kreuz 26f41000a8 Fix failing new WikiPage() call
Apparently this started to fail when the first character is not
capitalized.

Change-Id: Id9233984095652560cd473a33721f9835497b13b
2021-01-27 08:42:19 +01:00
Translation updater bot a059689440 Localisation updates from https://translatewiki.net.
Change-Id: I550836e9a5bf6c68eb188320a5b42e0c12e3bcff
2021-01-27 08:33:54 +01:00
Thiemo Kreuz 473a711aaa Rename our customized matchbrackets addon
Bug: T269096
Change-Id: I5b58099166f71ccc1b3b19334f28e8bbaafaceb3
2021-01-20 11:17:59 +01:00
jenkins-bot 9ab93e1c54 Merge "Lower maxHighlightLineLength limit to 5000" 2021-01-20 10:03:06 +00:00
Thiemo Kreuz 094f20902c Lower maxHighlightLineLength limit to 5000
While working on T270317, I realized the performance of the
matchbrackets addon is not as good as described in
T270237#6739993. The issue with my original benchmark was that
I did it with a single pair of brackets with thousands of
characters between. A paragraph with thousands of brackets
behaves much worse. So bad that I feels painful when moving
the cursor.

Lowering the limit to something in the middle (between the
original 1000 and my 10000) makes it behave much, much better
on my machine.

Bug: T270237
Bug: T270317
Change-Id: I31f850f4c7778d6b5ff1d0eb17fdaf0edf7ae019
2021-01-19 15:04:14 +01:00
WMDE-Fisch 7ec8ebc84d Concretised comment around WMDE disabled line
Change-Id: Ibc4e1568bae78e92371e21314edc16857be7afed
2021-01-19 13:21:48 +01:00
jenkins-bot 081071e534 Merge "Disable non-matching highlighting via config flag" 2021-01-19 08:46:42 +00:00
Thiemo Kreuz 18a64328bb Disable non-matching highlighting via config flag
My upstream patch was accepted within 9 minutes:
https://github.com/codemirror/CodeMirror/pull/6565

Note: This backport includes another upstream commit that fixed
some typos.

Bug: T269096
Change-Id: Ib5b64214d7536bc952886f45290d537eab2f9bbb
2021-01-18 09:51:05 +00:00
libraryupgrader 995d1ed3f2 build: Updating ini to 1.3.8
* https://npmjs.com/advisories/1589

Additional changes:
* Added the "composer phan" command to conveniently run phan.

Change-Id: I3911019defc17997ebf18b6102a9cf96bd06b1e4
2021-01-14 15:20:11 +00:00
Thiemo Kreuz a43acbeb6b Activate bracket matching for longer lines
The addon does have 3 settings:
- maxHighlightLineLength is for the current line where the
  cursor is. Bracket matching is simply not done when the
  current line is longer. The default is 1000, which is rather
  low.
- maxScanLineLength is for every other line that is scanned in
  the process. I don't understand why, but this limit is 10x
  higher.
- maxScanLines is the number of lines that can be scanned.

Simply raising the first to be 10000 as well fixes our issue.

Note that CodeMirror does have a limit of 10000 anyway. It's
called maxHighlightLength there. Lines that are longer get
syntax highlighting only for the first 10000 characters. The
rest of the line is black. Using the same limit in the addon
makes it's behavior consistent. Means: The user can see when
the syntax highlighting stops, and bracket matching stops
working the same time.

I benchmarked with both settings. It doesn't have a measurable
effect. Bracket matching is done in <1ms in both cases.

Bug: T270237
Change-Id: Ia56bf4c2fb023c9f117376242221d39f51196173
2021-01-14 11:28:02 +00:00
jenkins-bot ea8cffe3f2 Merge "Fix performance bottleneck in mediawiki syntax highlighter" 2021-01-14 11:22:33 +00:00
jenkins-bot 68ab91b64d Merge "Fix minor code style issues in matchbrackets addon" 2021-01-14 10:50:06 +00:00
Thiemo Kreuz 88984d2965 Fix minor code style issues in matchbrackets addon
Less ambiguous variable names. Less duplication. The minor
issues have been introduced in T270317.

Bug: T270317
Change-Id: I366396a61b76e19293ce8d14c2f346b97498fe40
2021-01-14 11:13:24 +01:00
Thiemo Kreuz f1cf1a534c Fix performance bottleneck in mediawiki syntax highlighter
I continued profiling the matchbrackets addon for T270237 and run into
performance issues that turned out to be unrelated to the addon. The
flame graph highlighted a "match" function. Note this is not the
String.match() from JavaScript, but something in the CodeMirror lib:

StringStream.prototype.match = function (pattern) {
  var match = this.string.match(pattern);
  if (match && match.index > 0) {
    return null;
  }
  return match;
}

(Note: I simplified this code so we can focus on the bug.)

When the pattern is a regular expression, it's executed via
JavaScript's String.match(). The function then checks if there was a
match and if it's at the start of the string. If not, it's not a
match and doesn't return one.

In other words: Even if there is a match somewhere in the string, the
function acts as if there was no match.

When we change all patterns to be anchored via ^, they don't scan the
entire string any more but return much ealier when there is no match
at the start of the string. We are effectively replacing nested loops
(hidden in the patterns) with single calls.

This bug exists since 2014.

The disabled line in the matchbrackets addon is just dead code. I
don't remove it to document the fact that we disabled it.

Bug: T270237
Bug: T270317
Change-Id: Icbb1122e6a3b26c0606726ff405e108931d185be
2021-01-13 16:58:57 +01:00
Thiemo Kreuz b0f9c23790 Update all syntax highlighters to latest version
We forgot to update these as well when we updated the lib.

Bug: T258999
Change-Id: I4dba51d82758975e46b75739c02ef2aa6cab5386
2021-01-13 09:41:29 +01:00
jenkins-bot 0bebeea02f Merge "Make private convertOffset function a shared method" 2021-01-13 07:22:29 +00:00
jenkins-bot 079a0ee325 Merge "Make bracket matching respect all limits" 2021-01-12 11:55:21 +00:00
jenkins-bot d01361dcdd Merge "Update matchbrackets addon to most recent version" 2021-01-12 11:48:28 +00:00
jenkins-bot 7f967cdd5d Merge "Add documentation for matchbrackets costomizations" 2021-01-12 11:48:26 +00:00
WMDE-Fisch de49f2c02a Enable bracket matching addon by defining the addons options
The addon does support some configuration options. These are passed
as properties of the `matchBrackets` CodeMirror option. Just passing
the boolean there hides that fact.

Bug: T270317
Bug: T270237
Change-Id: Iaa4b5ed8ef538e76cd1c96a09485e143112f1ae0
2021-01-12 11:55:22 +01:00
Adam Wight 27f964e240 Browser tests for CodeMirror (wikitext 2017 editor)
Bug: T270240
Change-Id: If1a2530e428122713277fbe87cd015cb729ab550
Depends-On: I2ba889e1a5dd03549d8d7cb00678a30882ff03fe
2021-01-11 12:47:49 +01:00
Thiemo Kreuz 0bb63f22d5 Make bracket matching respect all limits
This patch also removes all remaining FIXMEs. This code is not
a bottleneck. There is nothing to do.

Bug: T270317
Change-Id: Ie034440c98d8064a22811a1b569237dddb7b7436
2021-01-08 13:29:39 +01:00
jenkins-bot 217c17257a Merge "Browser tests for CodeMirror (wikitext 2010 editor)" 2021-01-08 11:22:16 +00:00
Thiemo Kreuz 111243bc19 Update matchbrackets addon to most recent version
We "forgot" to update this addon when we did the update in
I6f0f030 (T258999).

Bug: T258999
Bug: T270317
Change-Id: Iab29e9e36f34b76551ddac497e40dc76669ba7c7
2021-01-08 11:39:28 +01:00
Thiemo Kreuz e6ca95499a Add documentation for matchbrackets costomizations
Bug: T270317
Change-Id: Ifb09c9122e4002215dc47b6e4546adddb7608dbf
2021-01-08 11:33:22 +01:00
Adam Wight d6c6dbd73a Browser tests for CodeMirror (wikitext 2010 editor)
Basic tests to show that the highlighting classes have been attached
to the expected elements.

TODO in later patches:
* tests for the wikitext 2017 editor

Bug: T270240
Change-Id: I01ebd9881d38dd877f19ee3bb4fdcbb74d43afaf
2021-01-08 11:01:13 +01:00
Ed Sanders b59f296849 Guard against WikiEditor being removed by the time the hook runs
Bug: T271457
Change-Id: I73d2934847361592bceec51108404bf45ed4a5d7
2021-01-07 21:06:25 +00:00
Ed Sanders 7aceb6d65c Make private convertOffset function a shared method
Change-Id: I7e644ff998bd44e854b26dd9b11ba9a5d3bd0435
2021-01-06 14:57:32 +00:00
jenkins-bot 9b1b5795a6 Merge "Simplify onSelect handler implementation" 2021-01-06 11:20:44 +00:00
Thiemo Kreuz a43984fc67 Simplify onSelect handler implementation
Optimizations for the code introduced in Ic403e0a:
* Skip this entirely when something is selected (as discussed
  in Ic403e0a).
* Use a combination of existing methods. I benchmarked these
  again. This approach is "significantly" slower compared to
  the custom code from before. However, "significantly" here
  means something like 1 nanosecond vs. 4 nanoseconds. Both
  is effectively nothing.
* Use the same approach in another place. This one is triggered
  every time a change is made, e.g. a character typed. I
  benchmarked this as well. The new code is about 500x faster
  (yes, seriously).

Bug: T269094
Change-Id: I00fe595a89be7a257e27ed28d38568c81483338b
2021-01-05 22:50:04 +00:00
jenkins-bot 9a018ccb4a Merge "Provide cookie workaround for setting the feature flag" 2021-01-05 16:19:57 +00:00
jenkins-bot 773b308fab Merge "Integrated bracket matching for CodeMirror with VisualEditor" 2021-01-05 11:37:57 +00:00
Adam Wight 88fd6a4e28 Provide cookie workaround for setting the feature flag
This is a convenient way to propagate alternate configuration during
browser testing.

Bug: T270240
Change-Id: Ica6399c53499be7f930e8d13b838ad265b66cdf4
2021-01-04 16:09:11 +01:00
jenkins-bot 1ea61ad2aa Merge "Use wikiEditor.toolbarReady hook instead of ready event" 2020-12-31 03:29:51 +00:00
WMDE-Fisch 17fb4ceb7e Integrated bracket matching for CodeMirror with VisualEditor
Bug: T269094
Change-Id: Ic403e0a037127ed006e8d1168d710e6160a922d5
2020-12-29 21:34:16 +00:00
Ed Sanders 0c681f5300 ve-cm: Fix selection opacity when using fallback technique
The fallback technique makes the whole edit surface semi-transparent,
so reset native selections to full opacity.

Change-Id: If6cd585b1a09c549781fe82a3bdf18d64ac597b5
2020-12-28 23:38:16 +00:00
Ed Sanders 5bba5436a8 Use wikiEditor.toolbarReady hook instead of ready event
The hook avoids race conditions as it will run even if
CodeMirror loads after the toolbar.

Change-Id: Ida035fad473210add4a604b3c8d65d2d4edb49dc
2020-12-28 23:26:39 +00:00
Translation updater bot 16f8d02327 Localisation updates from https://translatewiki.net.
Change-Id: I8878e7489cff56f54ed7ca2bd058fb2ca70eebc1
2020-12-28 10:37:43 +01:00
libraryupgrader 65d92d8cb0 build: Updating mediawiki/mediawiki-phan-config to 0.10.6
Change-Id: I6744bcc582625b26a9fc9ca6666cff6ae48b1e56
2020-12-19 12:42:09 +00:00
Adam Wight d8f4982e79 Added bracket matching
* using CodeMirror addon matchBrackets
* highlights the matching bracket of a pair
* highlights brackets when cursor is inside a pair
* feature usable in source code editor

Bug: T261857
Change-Id: Ib01d9919a47bb29684b54501644b01936b57972a
2020-12-15 13:09:06 +00:00
libraryupgrader 4a6641f93a build: Updating ini to 1.3.8
* https://npmjs.com/advisories/1589

Change-Id: Iee4eda7181d333c3c18162347a8732eafd3c9bdc
2020-12-12 22:44:28 +00:00
jenkins-bot 8ef6d23814 Merge "Update CodeMirror to 5.58.3" 2020-12-10 08:49:44 +00:00
libraryupgrader b080db35f4 build: Updating mediawiki/mediawiki-phan-config to 0.10.5
Change-Id: Ic157781bf1ddd469dcb5b63c545c589f586616a8
2020-12-10 04:02:32 +00:00
Thiemo Kreuz 4a3c2dcad5 Update CodeMirror to 5.58.3
I had to make some CSS selectors more specific, because the
library changed

 .CodeMirror pre

to

 .CodeMirror pre.CodeMirror-line,
 .CodeMirror pre.CodeMirror-line-like

This is only relevant for entire lines (implemented as <pre>
elements). Most of the custom CSS is for characters, not lines.

In my tests in the Wikitext editor as well as VisualEditor I
could not spot any difference between the old and new version.

Bug: T258999
Change-Id: I6f0f030f972838727f3ef220feb105264f122798
2020-12-07 20:20:49 +00:00