profile
viewpoint
Thibaud Colas thibaudcolas @Torchbox Cambridge, UK https://thib.me/ I love cookies. JavaScript, React, accessibility.

springload/draftail 323

📝🍸 A configurable rich text editor built with Draft.js

springload/draftjs_exporter 60

Library to convert Draft.js ContentState to HTML

thibaudcolas/-_-.css 6

🙂_🙁.css – A mood-driven CSS framework to write modern websites using only emojis

gatensj/wagtail-draftail-katex 5

This will be an integration of a KaTek into the Wagtail CMS Draftail editor.

thibaudcolas/bitstarter 4

Node.js - powered crowdfunding platform, working with Bitcoins.

thibaudcolas/awesome-wagtail-stats 3

Awesome Wagtail package statistics

thibaudcolas/adventures-in-datascience 2

My adventures learning more data science and machine learning in particular

iGitScor/knov 1

Real-time culture sharer using Firebase as its backend and AngularJS on the frontend.

thibaudcolas/automation-sandbox 1

A safe place to play with various project automation techniques, particularly around software releases.

thibaudcolas/bakerydemo 1

Next generation Wagtail demo, born in Reykjavik

push eventthibaudcolas/thibaudcolas

Deployment Bot (from Travis CI)

commit sha 94269cf3c3faae8f7167906b4c32f1f3c0db88ab

Deploy thibaudcolas/thibaudcolas to github.com/thibaudcolas/thibaudcolas.git:gh-pages

view details

push time in 2 days

issue openedwagtail/wagtail

Documentation request: accessibility considerations for Wagtail sites

Reviewing the issues currently marked label:Accessibility, there are now quite a few that are about the accessibility of websites built with Wagtail, rather than the accessibility of the Wagtail admin UI. Wagtail generally tries to be un-opinionated about front-end markup, but there are quite a few areas where it has a lot of opinions, and I think it would be valuable to have a one-stop-shop document highlighting "things to consider for Wagtail websites to be accessible".

I see this as a single "Accessibility considerations for Wagtail websites" page, but it could also be split into separate parts of the documentation – feedback welcome.

Here is what this page would contain:

  • Images
    • alt text. Where it comes from in Wagtail (the title field by default). How to change that.
    • Images in rich text can override the alt text. Some implementations of the image chooser may allow that too. Document this.
  • Rich text
    • #4665
    • Disabling heading elements
  • TableBlock
    • #5989
    • How to make the "caption" field mandatory if appropriate
  • Embeds
    • #5982

I’ll update this list as I stumble upon more things like this.

created time in 2 days

issue commentwagtail/wagtail

Feature request: Switch TableBlock’s header controls to a field that requires user input

Marking this as "good first issue", and removing "Needs Design Decision" – if anyone wants to pick this up please post a comment and go ahead. Changing this require some Django knowledge, and changing the UI to a <select>. Not super straightforward but should be approachable, and it should be relatively self-contained / easy to write tests for.

thibaudcolas

comment created time in 2 days

issue commentwagtail/wagtail

Feature request: Switch TableBlock’s header controls to a field that requires user input

👍 good point, that seems like a neat solution. And we won’t have to change the table’s front-end rendering, which already works as intended with the current setup.

thibaudcolas

comment created time in 2 days

issue commentwagtail/wagtail

Richtext features bold and italic render as b and i should render as strong and em

Revisiting this again – I think #4223 will make it possible for people to fix this on their own websites without any change to Wagtail itself, however that still leaves us with the question of what would be the most appropriate default for Wagtail. I did more research.

HTML Specification

For the i element,

Authors are encouraged to consider whether other elements might be more applicable than the i element, for instance the em element for marking up stress emphasis, or the dfn element to mark up the defining instance of a term.

For the b element,

[...] should be used as a last resort when no other element is more appropriate. In particular, headings should use the h1 to h6 elements, stress emphasis should use the em element, importance should be denoted with the strong element, and text marked or highlighted should use the mark element.


WCAG

@allcaps already shared the relevant link at the top, https://www.w3.org/TR/WCAG20-TECHS/H49.html. The TL;DR; is "use semantic markup, strong and em".

Accessibility best practices

Here is the most authoritative information I could find: https://accessibility.psu.edu/boldfacehtml/. It’s really good so I’ll copy the relevant info here. Emphasis mine.

Many accessibility experts recommend using STRONG instead of B for bold face text, and EM instead of I for italic text. The reasons for this recommendation are:

STRONG and EM are semantic tags, meaning that they indicate that the author wishes to provide emphasis, which is rendered as bold/italic on a visual browser or in different speaking styles on a screen reader. In theory, screen readers could pronounce STRONG and EM in a different voice or style. However this rarely happens in practice (the same is true for B and I tags).

Why it’s not critical

On the other hand, real-world considerations make this distinction not as critical as other issues. Mainstream screen readers currently treat B/I tags identically to STRONG/EM tags. That is, they are ignored unless a user specifies that they be indicated. Some users report that announcing changes can be distracting. Many authors specify bold or italics purely for visual reasons in any case (in which case B/I might be preferred) or are not sure why they are adding the formatting, thus removing the utility of STRONG/EM. NOTE: No accessibility specifications require eliminating the use of the B and I tags, just that they be appropriately used.


I did my own testing as well and confirmed that screen readers do not announce strong/em/i/b any differently than normal runs of text. Tested with macOS VoiceOver, iOS VoiceOver, ChromeVox, and NVDA. I’d have ideally tested with JAWS as well but didn’t have it available.

Here is my test page if anyone wants to do their own testing: https://condescending-nobel-4e4e3c.netlify.app/


Based on all of this – I would recommend to keep Wagtail’s implementation as-is, and simply document the current state and how to configure this per-site in Wagtail’s rich text documentation once #4223 is merged. While in theory it feels to me like strong and em would be more appropriate, that’s only true if editors do use it in a semantic way (I’m happy to make that assumption) – and regardless, changing this doesn’t actually make a difference to screen reader users. So, there are more important things to worry about.

allcaps

comment created time in 2 days

Pull request review commenttorchbox/wagtailmedia

Add chooser upload form. Fix #22

+from wagtail import VERSION as WAGTAIL_VERSION++if WAGTAIL_VERSION < (2, 5):+    from wagtail.utils.pagination import paginate+else:+    from django.core.paginator import Paginator++    DEFAULT_PAGE_KEY = 'p'++    def paginate(request, items, page_key=DEFAULT_PAGE_KEY, per_page=20):+        paginator = Paginator(items, per_page)+        page = paginator.get_page(request.GET.get(page_key))+        return paginator, page

Yep, that works too!

teixas

comment created time in 2 days

issue commentthibaudcolas/-_-.css

It's too fast 😂

Hi Kalob,

Thanks for taking the time to report this. That’s a good point, and indeed that’s a known limitation of the approach we took in this framework. Perhaps this is something we should add opt-in support for, without changing the existing API? I’m thinking of something like:

@keyframes \⏳ {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.\🐢{
  animation-name: \⏳;
  animation-duration: 2s;
}

You could then use this as:

<body class="🦴 🐢">

This can be applied to all elements, but maybe it’s better to just support this for 🦴, with <body class="🦴 🦴--🐢">.

KalobTaulien

comment created time in 2 days

issue commentwagtail/wagtail

Automatic code formatting with Prettier

👍 I think we can pretty much paraphrase Django’s black DEP in this case, along with Prettier’s own "Why" https://prettier.io/docs/en/why-prettier.html.

yhoiseth

comment created time in 2 days

PR opened wagtail/stylelint-config-wagtail

Update package metadata + CI setup

The main change is:

Loosen stylelint-scss requirement to have no upper bound, as stylelint-scss supports all major versions of stylelint from v8.0.0 to v13.0.0.

This is so we can upgrade Wagtail to the latest stylelint without getting a peerDependency warning.

Additionally,

  • Adds a CI setup with GitHub Actions
  • Adds badges to the README
  • Slightly changes the package’s metadata
+22 -4

0 comment

5 changed files

pr created time in 3 days

create barnchthibaudcolas/stylelint-config-wagtail

branch : chore/package-metadata

created branch time in 3 days

create barnchthibaudcolas/stylelint-config-wagtail

branch : chore/package-metadata

created branch time in 3 days

created repositorythibaudcolas/stylelint-config-wagtail

created time in 3 days

PR closed wagtail/eslint-config-wagtail

Eslint upgrade

Extension of @lb-’s #3 – paraphrasing:

  • The tests are not fully working as yet but close
  • Added ONE extends (eslint:recommended) and reviewed all other rules, no changes needed
  • Remove two rules that are already part of eslint:recommended

Would love feedback on this, if we are good to go down this path.

Important: we should probably have a base and full config (similar to airbnb) as some projects will not use the react part, this has not been done yet.

+5932 -32

1 comment

13 changed files

thibaudcolas

pr closed time in 3 days

pull request commentwagtail/eslint-config-wagtail

Eslint upgrade

Re-opened at #5 with a branch that’s directly on the repository.

thibaudcolas

comment created time in 3 days

PR opened wagtail/eslint-config-wagtail

Eslint upgrade enhancement

Extension of @lb-’s #3 – paraphrasing:

  • The tests are not fully working as yet but close
  • Added ONE extends (eslint:recommended) and reviewed all other rules, no changes needed
  • Remove two rules that are already part of eslint:recommended

Would love feedback on this, if we are good to go down this path.

Important: we should probably have a base and full config (similar to airbnb) as some projects will not use the react part, this has not been done yet.

+553 -824

0 comment

9 changed files

pr created time in 3 days

create barnchwagtail/eslint-config-wagtail

branch : eslint-upgrade

created branch time in 3 days

PR opened wagtail/eslint-config-wagtail

Eslint upgrade

Extension of @lb-’s #3 – paraphrasing:

  • The tests are not fully working as yet but close
  • Added ONE extends (eslint:recommended) and reviewed all other rules, no changes needed
  • Remove two rules that are already part of eslint:recommended

Would love feedback on this, if we are good to go down this path.

Important: we should probably have a base and full config (similar to airbnb) as some projects will not use the react part, this has not been done yet.

+5932 -32

0 comment

13 changed files

pr created time in 3 days

push eventwagtail/eslint-config-wagtail

LB Johnston

commit sha 7f2335ec1b241fa2b2b16924cad911b956f0733e

Add License (MIT)

view details

LB Johnston

commit sha 19bdd6d7baed0e4fc507fada43239dbfd8e12b77

Add .editorconfig file

view details

LB Johnston

commit sha ba484aac477785981a61524512e45c8d9477e8e4

Add local eslintignore file

view details

LB Johnston

commit sha 1658c384f8be47402173993c370c2a5e184b6a2e

Add logging folders to Gitignore file

view details

LB Johnston

commit sha f2a1e5d2ad31d217b5e234930e6ec88011aa1063

Add nvmrc file

view details

LB Johnston

commit sha f115f6d15b501410adf4d33c9275120e59537e0c

Add links and contributing section to Readme file

view details

LB Johnston

commit sha 05a670a972a227157829933ac0efc9d95172dc16

Install Jest and Prettier for local development - move dependencies to near the top of the package.json file

view details

LB Johnston

commit sha dccb35a837d13a6843aba49eb4a8d2d64274314e

Configure Prettier (single quote)

view details

LB Johnston

commit sha 47f2e4308c7f5a2b933a398e1c314107deb1c2c5

Add basic local development npm scripts (lint, format and preflight)

view details

LB Johnston

commit sha 8bf5f63e2d9110ded79dd7a6b7c10f4f26231bd7

Add more npm keywords

view details

LB Johnston

commit sha 93907b2df28858d3df4d63e84d0c393d69684f46

Refine prettier configuration to align with other Wagtail projects - re-format index.js

view details

Thibaud Colas

commit sha b2e22de367e72e1f81a790f6ab0c60f5808269dd

Update .editorconfig

view details

Thibaud Colas

commit sha a345b1da90e0a9564e21610db4c6f981fca1b3ba

Update package.json

view details

Thibaud Colas

commit sha 969b8dc8e9216a40c3468cb7aacc3deeafa4d717

Update .nvmrc

view details

push time in 3 days

PR merged wagtail/eslint-config-wagtail

Eslint config project improvements enhancement

Do not merge this PR yet - discussion needed

The goal of this PR is to start to get this project updated to be easier to develop with, easier to update soon and to align with the new stylelint-config-wagtail project.

Discussion/WIP:

  • Are we happy to go in this direction
  • Tests need to be added (if practical, it might be easier to upgrade eslint first)
  • What version of eslint to align with, v6.0.0 alpha just came out, might be worth getting on this version as it progresses in the coming weeks

Improvements:

  • Add .editorconfig, prettier (formatting), jest (testing - no tests yet)
  • Add License
  • Fleshed out readme (with dev instructions)

Related Issues:

  • https://github.com/wagtail/wagtail/issues/5252
  • https://github.com/wagtail/wagtail/issues/5246
+6182 -11

2 comments

9 changed files

lb-

pr closed time in 3 days

push eventlb-/eslint-config-wagtail

Thibaud Colas

commit sha 7db4cc63d4fc39dccbf96f212438f901c610c17c

Update .nvmrc

view details

push time in 3 days

push eventlb-/eslint-config-wagtail

Thibaud Colas

commit sha d5ecb8bc07919240e577f72b98225bd331b0ea6f

Update package.json

view details

push time in 3 days

push eventlb-/eslint-config-wagtail

Thibaud Colas

commit sha fd7517e62f3907aed2eb46217e9dfca3de43c80e

Update .editorconfig

view details

push time in 3 days

Pull request review commentwagtail/eslint-config-wagtail

Eslint config project improvements

+# Defines the coding style for different editors and IDEs.+# http://editorconfig.org++root = true++[*]+end_of_line = lf+insert_final_newline = true+trim_trailing_whitespace = true++[*.{css,js,json,py,yml,rst}]+indent_style = space+max_line_length = 80++[*.{js,py}]+charset = utf-8++[*.{css,py,scss,rst}]+indent_size = 4++[*.{js,json,yml}]+indent_size = 2++[*.md]+trim_trailing_whitespace = false

Missing newline

trim_trailing_whitespace = false

lb-

comment created time in 3 days

Pull request review commentwagtail/eslint-config-wagtail

Eslint config project improvements

+10

Missing newline

10

lb-

comment created time in 3 days

Pull request review commentwagtail/eslint-config-wagtail

Eslint config project improvements

   "main": "index.js",   "scripts": {     "test": "eslint *.js"+    "format": "prettier --write '**/*.{js,md,css,scss,yaml,yml,json}'",+    "lint": "eslint ./ --max-warnings 0 && prettier --write '**/*.{js,md,css,scss,yaml,yml,json}'",+    "preflight": "npm run lint && npm run test",   },   "repository": {     "type": "git",     "url": "git+https://github.com/wagtail/eslint-config-wagtail.git"   },+  "dependencies": {+    "eslint-config-airbnb": "^9.0.1",+  },+  "devDependencies": {+    "eslint": "^2.12.0",+    "jest": "24.7.1",

Why pin to a specific version?

    "jest": "^24.7.1",
lb-

comment created time in 3 days

created tagwagtail/react-streamfield

tag0.9.6

Powerful field for inserting multiple blocks with nesting.

created time in 3 days

release wagtail/react-streamfield

0.9.6

released time in 3 days

push eventwagtail/react-streamfield

Thibaud Colas

commit sha daedf0a75294616114c6a000aa437c0077bdf562

Version 0.9.6.

view details

push time in 3 days

push eventwagtail/react-streamfield

Thibaud Colas

commit sha dc868e79eee439549c425c9c6d5d38181de08d53

Use wagtail gitignore

view details

Thibaud Colas

commit sha c3bbbae75057d64a95ef65227fa85161bca3a730

Show test coverage in CI

view details

push time in 3 days

push eventwagtail/react-streamfield

Thibaud Colas

commit sha 3d1d00dbd3cfcc9b87af4f56bba27d573c9e8874

Stop publishing uncompiled JS source

view details

Thibaud Colas

commit sha 2cee4b92e1d6904c1617b6f49bc9d5cfaf4e09e5

Add Travis badge in README

view details

push time in 3 days

push eventwagtail/react-streamfield

Thibaud Colas

commit sha 4a85d5bae93c4caa423a459a8d4680e0cc2f415e

List the published package’s content in CI

view details

push time in 3 days

push eventwagtail/react-streamfield

Thibaud Colas

commit sha 72aed81b28cc8218a0d5a25795a9db3531f24747

Add .nvmrc

view details

Thibaud Colas

commit sha 8e125c0760171760186dd739cf37d2050cea66fe

Add basic Travis configuration

view details

push time in 3 days

delete branch wagtail/react-streamfield

delete branch : chore/dependencies-cleanup

delete time in 3 days

push eventwagtail/react-streamfield

Thibaud Colas

commit sha 36cfab2307cc66ed8307e3865ae18ce39b7cc6cc

Remove unused prettier-stylelint in dependencies. Fix #11

view details

Thibaud Colas

commit sha 3b359644e2f8be5b1183324154c9bbaf998214b4

Merge pull request #12 from wagtail/chore/dependencies-cleanup

view details

push time in 3 days

issue closedwagtail/react-streamfield

prettier-stylelint should be in devDependencies

In the project’s package.json, prettier-stylelint is defined in dependencies: https://github.com/wagtail/react-streamfield/blob/b13b41fd382445bd5fe1ebb63224bdfa0007e219/package.json#L35-L41.

This is problematic as it pollutes every codebase that react-streamfield is installed in, unnecessarily installing a lot of extra dependencies.

closed time in 3 days

thibaudcolas

PR merged wagtail/react-streamfield

Remove unused prettier-stylelint in dependencies. Fix #11 bug

See #11 for the reason why this is a problem. Prettier isn’t configured on the project so I’ve removed the dependency, which does nothing as far as I can tell.

+439 -557

0 comment

2 changed files

thibaudcolas

pr closed time in 3 days

PR opened wagtail/react-streamfield

Remove unused prettier-stylelint in dependencies. Fix #11

See #11 for the reason why this is a problem. Prettier isn’t configured on the project so I’ve removed the dependency, which does nothing as far as I can tell.

+439 -557

0 comment

2 changed files

pr created time in 4 days

create barnchwagtail/react-streamfield

branch : chore/dependencies-cleanup

created branch time in 4 days

startedwagtail/wagtail-airtable

started time in 4 days

delete branch thibaudcolas/wagtailmedia

delete branch : chore/demo-site-migration

delete time in 4 days

push eventtorchbox/wagtailmedia

Thibaud Colas

commit sha 6c6593c1d764e08e2acf2a1fa8bc2e2e06ab944e

Remove "b" bytes literal marker from initial migration of test app (#96)

view details

push time in 4 days

PR merged torchbox/wagtailmedia

Remove "b" bytes literal marker from initial migration of test app enhancement

Discussed on Slack – this causes a migration to show whenever running the demo site, and seems to only be a remnant of Python 2 support.

There shouldn’t be any adverse consequences of updating the existing migration directly – so I’m tempted to merge this without further review, but I’ll leave it open for a few days in case others disagree.

+5 -5

0 comment

1 changed file

thibaudcolas

pr closed time in 4 days

issue commentwagtail/wagtail

Automatic code formatting with Prettier

Hey @yhoiseth, just looking at your PRs – at this stage I think it’s too early to make PRs for this. As I said in my comment what we really need right now is a proposal so we can discuss what we want to do.

If we take the black DEP as a reference – I think what we need is just the Reference implementation, with details of the steps involved.

Here’s what to cover:

  • How we should configure Prettier, based on our existing styleguide(s) and best practices
  • Updating our ESLint and stylelint configurations to be compatible
  • Formatting the code – how we do (personally I’d rather have this not done in the same PR as with the other changes, as it will make it go outdated all the time)
  • Enforcement - where do we run Prettier in CI, and what changes do we need to make
  • Documentation – where do we need to upgrade our code styleguide, and where do we need instructions on Prettier usage.
yhoiseth

comment created time in 4 days

PR closed wagtail/wagtail

6059 prettier

See #6059.

+9962 -9061

2 comments

223 changed files

yhoiseth

pr closed time in 4 days

pull request commentwagtail/wagtail

6059 prettier

It looks like #6065 replaces this so I’ll close this PR. Please don’t leave PRs open if they are replaced by other ones.

yhoiseth

comment created time in 4 days

push eventthibaudcolas/wagtail

Thibaud Colas

commit sha 314a926f75f96275ccd9c84a568d7e588f13b258

Update Python and JS test coverage collection to exclude tests

view details

jacobtoppm

commit sha 6da415335ade1c0d40579bfbc1903cc71adbac0c

Update php-date-formatter to 1.3.6 in vendor js to prevent datetimepicker 12 hour time issue where it would reduce the time by an hour each time the widget lost focus

view details

jacobtoppm

commit sha da3c162d4d6e24b582a81730cd21b2c809e7aa87

Make datetimepicker consistent with USE_L10N=True by allowing it to override the WAGTAIL_x_FORMAT settings. Add a new setting, WAGTAIL_TIME_FORMAT, to specify the time formatting for the timepicker widget and the input format.

view details

jacobtoppm

commit sha 38f18ae98bcb3007ed0b439d9150b33a9ac7477b

Allow the timepicker widget width to vary to account for longer time formats

view details

jacobtoppm

commit sha ba4a72d867b44801af488c7589f13641be5f6c4f

Add tests for new date/time widget behaviour

view details

jacobtoppm

commit sha ead6c8b2a649f5ab774cf45a174bfdd81ba15a42

Add WAGTAIL_TIME_FORMAT to settings reference

view details

Matt Westcott

commit sha c3a7efa7a16983b0f9878e07b0a18fc876254bc3

Revert prioritisation of USE_L10N=True over WAGTAIL_*_FORMATS

view details

Matt Westcott

commit sha ab71e515e45ad0c29ab2da15bb91dce6cb37d680

Release notes for #6057

view details

Scott Cranfill

commit sha 8c6c7b8c77716289a5a01717cc72a74d5d9cdf3b

Fix JS linting issue that slipped into SVG icon PR

view details

Coen van der Kamp

commit sha afa640fa14f3e875999e94cbe96caac3726f8812

Translate site default label

view details

Karl Hobley

commit sha 899737012669ec975634dde6bd370a352a34209e

Return all results when no search terms specified This lets search filters work when there is no search query.

view details

Karl Hobley

commit sha 88cff1f69e1ed32b4f5dfabe97ed98e35461b85d

Remove extra quotes around query string when no matches found

view details

push time in 4 days

delete branch wagtail/wagtail

delete branch : fix-js-lint-issue

delete time in 4 days

delete branch thibaudcolas/wagtail

delete branch : chore/code-coverage-tests

delete time in 4 days

pull request commentwagtail/wagtail

Fix RestaurantTag migration tests introducing an extra migration

Damn, sorry! I must have been running with tests with an out-of-date master.

thibaudcolas

comment created time in 4 days

push eventthibaudcolas/wagtail

Thibaud Colas

commit sha 471823f2384f7c8d64d7866025f95c8eb929056f

Upgrade to Jest 23 * Jest 24 is out but upgrading to it would require us to also update our Webpack tooling to Babel 7, which is quite significant work. * Rewrite Draftail initialisation tests to stop relying on jsdom script parsing

view details

Thibaud Colas

commit sha 7eeb44ad0408cf72060f19db577de2159859cd74

Replace gulp-sass with gulp-dart-sass * Rewrite Sass code that relies on deprecated or removed features in Dart Sass * Remove unneeded rebuild of node-sass * Update lockfile

view details

Matt Westcott

commit sha 52013f492049c4e2d7964cdf9b699cd6609b7421

Mention INSTALLED_APPS ordering in custom user docs

view details

Karl Hobley

commit sha 58f6aecfc7b305c2f3497984aebbe0c3bb2debda

Some cleanups in PostgreSQL search module (#5953) * Separated logic for extracting indexable content * Docs edits * Readability improvements * Simplify/deduplicate indexing code * Simplify search code Pulled in some code that will be included in a future Django release (query.py) * Reword a limitation * Fix typo in docstring * Raise a warning when Boost() is used in PostgreSQL search backend * Add note mentioning that RawSearchQuery can be replaced in Django 3.1 * Add comment mentioning that we can replace query.py if Django PR merged

view details

Coen van der Kamp

commit sha 99abab5d6ba8ef9b65779a1aab2498991d129347

Add section to explain commit to pull request

view details

Karl Hobley

commit sha 70c5dcf80f861353b467e6f798a96ae42129ab29

Add "Programming Rust" book to search fixture

view details

Karl Hobley

commit sha 55db4646ed13517fed9a004b674de7d3e4c43308

Add Phrase() query class and test

view details

Karl Hobley

commit sha a67ac1aa1d8bbe03ef73d27cc08bbec463f1d236

Implement Phrase() query in database backend

view details

Karl Hobley

commit sha b320ac791040bb58e6d7837743563d8539f5d664

Implement Phrase() query in PostgreSQL backend

view details

Karl Hobley

commit sha a501dc257d086ea4c9d38398a0cc29dc3aaa6f76

Implement Phrase() query in Elasticsearch backend

view details

Karl Hobley

commit sha 81811f6c1ce7edeef1ce274ce8ec6e52d371aa5e

Documentation for phrase search and query classes

view details

Karl Hobley

commit sha 7d32a4fd2153ea36df4ebdaf995b1ff559c1b825

Implemented MATCH_NONE query

view details

Karl Hobley

commit sha a2bfb193b632cf7729d1a9f1206345f7310354f3

Added query parser and use it in the admin

view details

Karl Hobley

commit sha 3d645fad53e3716aca91e8664ad1b45cc50cb508

Make database backend handle MATCH_ALL/MATCH_NONE properly

view details

Karl Hobley

commit sha 9dd9d0c89587ba5fd5b2ad87aca27fcb87809a26

Docs for parse_query_string

view details

Matt Westcott

commit sha 92e9e156839e884d16c80d72f27baa27684c659f

Release note for phrase search / search query expressions

view details

Matt Westcott

commit sha dcb517f080e255122acd6d675468ed881c1fe97c

Changelog note for phrase search / search query expressions

view details

Coen van der Kamp

commit sha eed16e00348c6ddfe8f997e1150006a3211a1216

Add SVG Icons and include in admin menu * This commit only covers the migration of the icons in the menu and draftail editor. All other admin menu icons remain implemented as before. * Existing font based icon support still exists. * Convert menu icons to SVG * This could be considered a breaking change for any Wagtail sites or packages that are leveraging Wagtail's Button and Icon React components. * Remove references to unused `submenu-trigger` class * Prefix icon `id`s with `icon-` to prevent `id` collisions * Add hooks support (not yet documented) for adding custom icons

view details

Coen van der Kamp

commit sha a1a2c35c1c1e78efa38bed0074ae0c7968770e84

Template render richtext without wrapper, add wagtail.contrib.legacy.richtext * Add wagtail.contrib.legacy.richtext with tests & docs * Make RichText.__html__ behave the same as template filter * Resolves #1214

view details

Timothy Bautista

commit sha 1958bba2476c32069acafd6837514749a4d3ceea

Fix typo in 2.10 release notes doc

view details

push time in 5 days

push eventthibaudcolas/wagtail

Thibaud Colas

commit sha bb838015325153382acec3637e0c315027beeb52

Fix RestaurantTag migration tests introducing an extra migration (#6075) Due to the verbose_name being lowercased in django-taggit v1.3.0, https://github.com/jazzband/django-taggit/commit/90c7224018c941b9a260c8e8bed166536f5870df.

view details

Thibaud Colas

commit sha bcd2006525d11abaa4611978af223b98f08d5dc2

Update Python and JS test coverage collection to exclude tests

view details

push time in 5 days

pull request commentwagtail/wagtail

Fix RestaurantTag migration tests introducing an extra migration

🎉 that was quick!

thibaudcolas

comment created time in 5 days

delete branch thibaudcolas/wagtail

delete branch : chore/taggit-1.3.0-lowercase

delete time in 5 days

pull request commentwagtail/wagtail

Update Python and JS test coverage collection to exclude tests

Ready for review now that both django-taggit problems seem to be addressed.

thibaudcolas

comment created time in 5 days

Pull request review commenttorchbox/wagtailmedia

Add chooser upload form. Fix #22

+from wagtail import VERSION as WAGTAIL_VERSION++if WAGTAIL_VERSION < (2, 5):+    from wagtail.utils.pagination import paginate+else:+    from django.core.paginator import Paginator++    DEFAULT_PAGE_KEY = 'p'++    def paginate(request, items, page_key=DEFAULT_PAGE_KEY, per_page=20):+        paginator = Paginator(items, per_page)+        page = paginator.get_page(request.GET.get(page_key))+        return paginator, page

Hmm yes, it looks like that worked and the conflicts are gone, but now your PR contains changes that are unrelated to it.

I’ve tried to do it myself with git rebase -i master, which is slightly more tricky to use. Here is the result for me, with your three commits: https://github.com/thibaudcolas/wagtailmedia/tree/teixas-chooser-upload-form.

teixas

comment created time in 5 days

create barnchthibaudcolas/wagtailmedia

branch : teixas-chooser-upload-form

created branch time in 5 days

issue openedwagtail/react-streamfield

prettier-stylelint should be in devDependencies

In the project’s package.json, prettier-stylelint is defined in dependencies: https://github.com/wagtail/react-streamfield/blob/b13b41fd382445bd5fe1ebb63224bdfa0007e219/package.json#L35-L41.

This is problematic as it pollutes every codebase that react-streamfield is installed in, unnecessarily installing a lot of extra dependencies.

created time in 5 days

push eventthibaudcolas/wagtail

Dan Bentley

commit sha f43db1e69e67946b08207aeb39e2949f907bba2e

Fetch and apply annotations if using specific()

view details

Matt Westcott

commit sha a7ddb056b82c449753e44f09849ba0696750340a

Fix test suite migrations to match django-taggit 1.3.0

view details

GTpyro

commit sha 147fda12fabb681cf0c2a80b7a4d9b11b06f589b

Update signals.rst for Python 3 compatibility The send_to_slack example was not compatible with Python 3. Example is updated using the requests & json libraries (instead of urllib & urllib2)

view details

Martin Sandström

commit sha f4542c8ffc93633c0e8751bd2860f440d44b1fa7

Fix that proper document icon are shown

view details

Thibaud Colas

commit sha a895756f9a4b7ca8f4eee358ffcc48e882f099b4

Fix RestaurantTag migration tests introducing an extra migration Due to the verbose_name being lowercased in django-taggit v1.3.0, https://github.com/jazzband/django-taggit/commit/90c7224018c941b9a260c8e8bed166536f5870df.

view details

Thibaud Colas

commit sha aad6ee820ddd4f51d7c3cf138bf32c6593e2bab4

Update Python and JS test coverage collection to exclude tests

view details

push time in 5 days

PR opened wagtail/wagtail

Fix RestaurantTag migration tests introducing an extra migration Release blocker component:Tagging status:Needs Review type:Cleanup/Optimisation

Follow-up for https://github.com/wagtail/django-modelcluster/pull/123, fixing another change in django-taggit 1.3.0 that breaks our tests. For this one I’m pretty sure this just breaks Wagtail’s tests but has no other consequences for websites (well, except for the extra migration they’ll get as well).

Since those migrations are just here for tests I’ve assumed it was ok to edit the existing migration as the only change is with verbose_name.

Change from django-taggit: https://github.com/jazzband/django-taggit/commit/90c7224018c941b9a260c8e8bed166536f5870df


  • [x] Do the tests still pass? (https://docs.wagtail.io/en/latest/contributing/developing.html#testing)
  • [x] Does the code comply with the style guide? (Run make lint from the Wagtail root)
  • [x] For Python changes: Have you added tests to cover the new/fixed behaviour?
  • ~[ ] For front-end changes: Did you test on all of Wagtail’s supported browsers? Please list the exact versions you tested.~
  • ~[ ] For new features: Has the documentation been updated accordingly?~
+2 -2

0 comment

1 changed file

pr created time in 5 days

create barnchthibaudcolas/wagtail

branch : chore/taggit-1.3.0-lowercase

created branch time in 5 days

PR opened torchbox/wagtailmedia

Remove "b" bytes literal marker from initial migration of test app

Discussed on Slack – this causes a migration to show whenever running the demo site, and seems to only be a remnant of Python 2 support.

There shouldn’t be any adverse consequences of updating the existing migration directly – so I’m tempted to merge this without further review, but I’ll leave it open for a few days in case others disagree.

+5 -5

0 comment

1 changed file

pr created time in 5 days

create barnchthibaudcolas/wagtailmedia

branch : chore/demo-site-migration

created branch time in 5 days

Pull request review commenttorchbox/wagtailmedia

Add chooser upload form. Fix #22

+from wagtail import VERSION as WAGTAIL_VERSION++if WAGTAIL_VERSION < (2, 5):+    from wagtail.utils.pagination import paginate+else:+    from django.core.paginator import Paginator++    DEFAULT_PAGE_KEY = 'p'++    def paginate(request, items, page_key=DEFAULT_PAGE_KEY, per_page=20):+        paginator = Paginator(items, per_page)+        page = paginator.get_page(request.GET.get(page_key))+        return paginator, page

You shouldn’t need to make a new PR. First pull the latest master from this repository to your fork’s master, then here are the best two options, from your chooser-upload-form:

  • git rebase master to rebase your commits as if they had been done on top of the latest master. This will either prompt you to fix the conflicts due to this code being added twice (once in master, once in your branch) – or automagically figure out that there is no need for the same change twice (unlikely here I think)
  • git merge master to create a merge commit of the new master into your branch. This merge commit will be removing that code.

It’s an important part of making pull requests to keep them up-to-date with a project’s changes, so worth your time learning this IMHO, but if this goes over your head I’m also happy to do it myself once I get back to your PR.

teixas

comment created time in 5 days

pull request commenttorchbox/wagtailmedia

Add chooser upload form. Fix #22

@teixas thank you!

teixas

comment created time in 5 days

startedalphagov/accessibility-tool-audit

started time in 5 days

IssuesEvent

issue commentspringload/draftail

Example of using Draftail without React

Thanks for the feedback but I’m not sure I agree. I’ve added this specifically because people were asking whether it was possible to use Draftail on projects that don’t use React, and the answer is yes, but you of course have to install it at least for Draftail, since Draftail depends on it.

I’ll see if I can find a way to rephrase this, or maybe add an example as you mentioned.

jkevingutierrez

comment created time in 6 days

startedhtmlhint/HTMLHint

started time in 6 days

PR opened pa11y/pa11y

WIP: Add lower-level runner API to support non-browser runners

Initially discussed on Slack. Currently just a draft PR with lots of missing parts.

Pa11y supports custom runners, but those runners are only executed within the context of the browser (with Puppeteer’s page.evaluate). I would like to make runners that rely on "server-side" processing, either Node modules that cannot run in the browser, or CLI tools from other languages that can only be integrated with Node code.

This PR reworks the runners’ integration to introduce a new lower-level API that supports the scenario described above, as well as making it possible for runners to manipulate the Puppeteer page if they want to – e.g. to read the page’s accessibility tree, or see if the page has horizontal scrolling on smaller viewport sizes.


This implementation does two things:

  • Moves the logic of executing individual runners and collating their issues from the browser context to Node. This change alone should be completely backwards-compatible and not impact Pa11y’s behavior.
  • Introduces a new "processPage" method for runners, which is invoked instead of run when present, and gives runners access to the Puppeteer page, expecting an array of issues back.

I’m not particularly convinced this is the best abstraction / API, but it’s the one that was the least work to get experimenting with.

There are a few things I haven’t touched yet and would likely need to address in some way:

  • loadRunnerScript still executes even if the runner has no scripts nor run method.
    • Because of this, the runner still needs to have an empty scripts: [], and run: () => {}.
    • assertReporterCompatibility only runs within loadRunnerScript. If loadRunnerScript is changed, that compatibility check would need to be done elsewhere.
  • All of the issue filtering logic is still in the Pa11y browser runner context only, and it’s unclear how compatible it would be with runners that aren’t in the browser,
    • Retrieving the context and selector as Pa11y does relies on the runner providing a DOM element.
    • The ignore by code only works for runners that have codes :)
    • The rootElement filtering depends on the DOM
    • hideElements also depends on the DOM

To try this out, here are install instructions with the runner I’m currently working on based on the v.Nu HTML validator:

# On macOS,
brew install vnu
# Elsewhere, grab the latest release from
# https://github.com/validator/validator/releases/latest.
# Make sure the `vnu` executable is in your PATH.
# Then,
npm install -g https://github.com/thibaudcolas/pa11y#feature/node-runners pa11y-runner-vnu

pa11y --runner vnu https://www.example.com/

<details>

<summary>Output</summary>

$ pa11y --runner vnu https://www.example.com/

Welcome to Pa11y

 > Running Pa11y on URL https://www.example.com/

Results for URL: https://www.example.com/

 • Error: A document must not include both a “meta” element with an “http-equiv” attribute whose value is “content-type”, and a “meta” element with a “charset” attribute.
   ├── html-validation
   ├──
   └── f-8"> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <

 • Notice:  The “type” attribute for the “style” element is not needed and should be omitted.
   ├── html-validation
   ├──
   └── e=1"> <style type="text/css"> b

 • Notice: Consider adding a “lang” attribute to the “html” start tag to declare the language of this document.
   ├── html-validation
   ├──
   └── TYPE html><html><head>

1 Errors
2 Notices

</details>

Here is the source of that runner: pa11y-runner-vnu, and extra install instructions. If you don’t want to install vnu, here is a much simpler dummy runner you can try this with:

module.exports = {
  // Update this when an API-compatible Pa11y gets released.
  supports: "^6.0.0-alpha || ^6.0.0-beta",
  // Needs to be defined even if this runner does not rely on any scripts.
  scripts: [],
  // needs to be defined even though it’s empty.
  run: () => {},
  processPage: async (page) => {
    const html = await page.content();

    if (!html.includes("<html lang=")) {
      return [
        {
          code: "html-has-lang",
          message: "<html> elements must have a `lang` attribute",
          type: "error",
          context: "",
          selector: "",
        },
      ];
    }

    return [];
  },
};
+44 -22

0 comment

2 changed files

pr created time in 7 days

push eventthibaudcolas/pa11y-runner-vnu

Thibaud Colas

commit sha 5f26e64c89fdb49597789896cae34162ef74728b

docs(readme): add "Why" section to README

view details

push time in 7 days

release thibaudcolas/pa11y-runner-vnu

v0.1.0

released time in 7 days

push eventthibaudcolas/pa11y-runner-vnu

Thibaud Colas

commit sha 8b46fee2dbbf63221314694f6607a1356c176bd4

docs(readme): add npm badge and link

view details

push time in 7 days

push eventthibaudcolas/pa11y-runner-vnu

Thibaud Colas

commit sha 15411d5b93fe086a0988091b26821dcbfa69661e

chore(release): v0.1.0

view details

push time in 7 days

created tagthibaudcolas/pa11y-runner-vnu

tagv0.1.0

created time in 7 days

push eventthibaudcolas/pa11y-runner-vnu

Thibaud Colas

commit sha 9ae4d3cb5c0e9044ed5c920f2d47eafdde22884e

chore: first commit

view details

Thibaud Colas

commit sha fb6aac76ba6d9bddd205807e0db5206392aa5183

chore(qa): add test script directly in the project

view details

Thibaud Colas

commit sha e6132d20bfa630ed01e394f915c76e749946eb1e

docs(readme): add LGTM badges

view details

Thibaud Colas

commit sha 1023fa8b79b1808e2161166464b2511436f78086

docs(readme): add usage instructions that work

view details

push time in 7 days

create barnchthibaudcolas/pa11y

branch : feature/node-runners

created branch time in 7 days

create barnchthibaudcolas/pa11y-runner-vnu

branch : master

created branch time in 7 days

startedthibaudcolas/pa11y-runner-vnu

started time in 7 days

created repositorythibaudcolas/pa11y-runner-vnu

created time in 7 days

startedspringernature/frontend-playbook

started time in 7 days

startedbrowniebroke/django-codemod

started time in 7 days

startedlocustio/locust

started time in 7 days

startedIBMa/equal-access

started time in 7 days

starteddjango/deps

started time in 7 days

push eventthibaudcolas/draftjs-conductor

renovate[bot]

commit sha c362c0d3eed8729d40e09775a3d06509c172324e

chore(deps): update rollup to v2.10.9 (#194)

view details

push time in 7 days

delete branch thibaudcolas/draftjs-conductor

delete branch : renovate/rollup

delete time in 7 days

PR merged thibaudcolas/draftjs-conductor

chore(deps): update rollup to v2.10.9 enhancement

This PR contains the following updates:

Package Update Type Change Sourcegraph
rollup (source) patch devDependencies 2.10.8 -> 2.10.9 code search for "rollup"

Release Notes

<details> <summary>rollup/rollup</summary>

v2.10.9

Compare Source

2020-05-24

Bug Fixes
  • Prevent invalid exports when facades are created (#​3590)
Pull Requests
  • #​3590: Prevent unneeded exports when entry facades are created and ensure all exported variables in facades are imported (@​lukastaegert)

</details>


Renovate configuration

:date: Schedule: "every weekend" (UTC).

:vertical_traffic_light: Automerge: Enabled.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+4 -4

0 comment

2 changed files

renovate[bot]

pr closed time in 7 days

issue commenttorchbox/wagtailmedia

Feature Request: Embed media in rich text fields using Draftail

I’ve done an initial review review of #90. I think more feedback on the approach (not necessarily the details of the implementation) would be helpful.

juan0tron

comment created time in 8 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

 def get_media_form(model):     ],     'wagtailmedia/permissions/includes/media_permissions_formset.html' )+++class MediaInsertionForm(forms.Form):+    """+    Form for customizing media player behavior (e.g. autoplay by default)+    prior to insertion into a rich text area+    """+    autoplay = forms.BooleanField(required=False)

I wouldn’t ever recommend anyone make anything autoplay, although I know some people might. How can we make the presence of this field configurable?

juan0tron

comment created time in 9 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

+const React = window.React;+const ReactDOM = window.ReactDOM;+const Modifier = window.DraftJS.Modifier;+const EditorState = window.DraftJS.EditorState;+const AtomicBlockUtils = window.DraftJS.AtomicBlockUtils;++/**+ *  Choose a media file in this modal+ */+class WagtailMediaChooser extends window.draftail.ModalWorkflowSource {+    componentDidMount() {+        const { onClose, entityType, entity, editorState } = this.props;++        $(document.body).on('hidden.bs.modal', this.onClose);++        this.workflow = global.ModalWorkflow({+            url: `${window.chooserUrls.mediaChooser}?select_format=true`,+            onload: MEDIA_CHOOSER_MODAL_ONLOAD_HANDLERS,+            urlParams: {},+            responses: {+                mediaChosen: (data) => this.onChosen(data)+            },+            onError: (err) => {+                console.error("WagtailMediaChooser Error", err);+                onClose();+            },+        });+    }++    onChosen(data) {+        const { editorState, entityType, onComplete } = this.props;++        const content   = editorState.getCurrentContent();+        const selection = editorState.getSelection();++        const entityData = data;+        const mutability = 'IMMUTABLE';++        const contentWithEntity = content.createEntity(entityType.type, mutability, entityData);+        const entityKey         = contentWithEntity.getLastCreatedEntityKey();+        const nextState         = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ');++        this.workflow.close();++        onComplete(nextState);+    }+}++// Constraints the maximum size of the tooltip.+const OPTIONS_MAX_WIDTH  = 300;+const OPTIONS_SPACING    = 70;+const TOOLTIP_MAX_WIDTH  = OPTIONS_MAX_WIDTH + OPTIONS_SPACING;++/**+ *	Places media thumbnail HTML in the Rich Text Editor+ */+class WagtailMediaBlock extends React.Component {+    constructor(props) {+        super(props);++        this.state = {+            showTooltipAt: null,+        };++        this.setState      = this.setState.bind(this);+        this.openTooltip   = this.openTooltip.bind(this);+        this.closeTooltip  = this.closeTooltip.bind(this);+        this.renderTooltip = this.renderTooltip.bind(this);+    }++    componentDidMount() {+        document.addEventListener('mouseup', this.closeTooltip);+        document.addEventListener('keyup', this.closeTooltip);+        window.addEventListener('resize', this.closeTooltip);+    }++    openTooltip(e) {+        const { blockProps } = this.props;+        const { entity, onRemoveEntity } = blockProps;+        const data = entity.getData();++        const trigger = e.target.closest('[data-draftail-trigger]');++        if (!trigger) return; // Click is within the tooltip++        const container = trigger.closest('[data-draftail-editor-wrapper]');++        if (container.children.length > 1) return;  // Tooltip already exists++        const containerRect = container.getBoundingClientRect();+        const rect = trigger.getBoundingClientRect();+        const maxWidth = trigger.parentNode.offsetWidth - rect.width;+        const direction = maxWidth >= TOOLTIP_MAX_WIDTH ? 'left' : 'top-left'; // Determines position of the arrow on the tooltip++        let top  = 0;+        let left = 0;++        if(direction == 'left'){+            left = rect.width + 50;+            top  = rect.top - containerRect.top + (rect.height / 2);+        }+        else if (direction == 'top-left'){+            top = rect.top - containerRect.top + rect.height;+        }++        this.setState({+            showTooltipAt: {+                container: container,+                top: top,+                left: left,+                width: rect.width,+                height: rect.height,+                direction: direction,+            }+        });+    }++    closeTooltip(e) {+        if(e.target.classList){+            if(e.target.classList.contains("Tooltip__button")){+                return; // Don't setState if the "Delete" button was clicked+            }+        }+        this.setState({ showTooltipAt: null });+    }++    /**+     * Returns either a tooltip "portal" element or null+     */+    renderTooltip(data) {+        const { showTooltipAt } = this.state;+        const { blockProps } = this.props;+        const { entity, onRemoveEntity } = blockProps;++        // No tooltip coords exist, don't show one+        if(!showTooltipAt) return null;++        let options = []+        if(data.autoplay) options.push("Autoplay");+        if(data.mute) options.push("Mute");+        if(data.loop) options.push("Loop");+        const options_str = options.length ? options.join(", ") : "";++        return ReactDOM.createPortal(React.createElement('div', null,+            React.createElement('div',+                {+                    style: {+                        top: showTooltipAt.top,+                        left: showTooltipAt.left+                    },+                    class: "Tooltip Tooltip--"+showTooltipAt.direction,+                    role:  "tooltip"+                },+                React.createElement('div', { style: { maxWidth: showTooltipAt.width } }, [+                    React.createElement('p', {+                        class: "ImageBlock__alt"+                    }, data.type.toUpperCase()+": "+data.title),+                    React.createElement('p', { class: "ImageBlock__alt" }, options_str),+                    React.createElement('button', {+                        class: "button button-secondary no Tooltip__button",+                        onClick: onRemoveEntity+                    }, "Delete")+                ])+            )+        ), showTooltipAt.container);+    }++    render() {+        const { blockProps } = this.props;+        const { entity } = blockProps;+        const data = entity.getData();++        let icon;+        if(data.type == 'video'){+            icon = React.createElement('span',  { class:"icon icon-fa-video-camera", 'aria-hidden':"true" });+        }+        else if(data.type == 'audio'){+            icon = React.createElement('span',  { class:"icon icon-fa-music", 'aria-hidden':"true" });+        }++        return React.createElement('button',+            {+                class: 'MediaBlock WagtailMediaBlock '+data.type,+                type:  'button',+                tabindex: '-1',+                'data-draftail-trigger': "true",+                onClick: this.openTooltip,+                style: { 'min-width': '100px', 'min-height': '100px'}+            },+            [+                React.createElement('span',+                    { class:"MediaBlock__icon-wrapper", 'aria-hidden': "true" },+                    React.createElement('span', {}, icon)+                ),+                React.createElement('img', { src: data.thumbnail }),

Needs an alt="" attribute to be valid HTML

juan0tron

comment created time in 9 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

 def describe_collection_media(collection):             ) % {'count': media_count},             'url': url,         }+++@hooks.register('register_rich_text_features')+def register_custom_media_feature(features):+    # Register a handler for converting <embed type="customimage"> to frontend HTML+    if WAGTAIL_VERSION < (2, 5):+        features.register_embed_type(embed_type='media', handler=MediaEmbedHandler)+    else:+        features.register_embed_type(MediaEmbedHandler)++    feature_name = 'wagtailmedia'++    control = {+        'type': 'MEDIA',+        'icon': 'media',+        'description': 'Media',+    }++    plugin_js = [+        'wagtailmedia/js/media-chooser-modal.js',+        'wagtailmedia/js/WagtailMediaBlock.js',+    ]++    features.register_editor_plugin(+        'draftail',+        feature_name,+        draftail_features.EntityFeature(control, js=plugin_js)+    )++    features.register_converter_rule(+        'contentstate',+        feature_name,+        ContentstateMediaConversionRule+    )++    features.default_features.append(feature_name)

I don’t think it should be enabled by default for all fields.

juan0tron

comment created time in 9 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

+{% block video %}+	<video class="wagtailmedia-video"+		controls+		{% if mute %}muted{% endif %}+		{% if autoplay %}autoplay{% endif %}+		{% if loop %}loop{% endif %}+		{% if thumbnail %}poster="{{thumbnail}}"{% endif %}>+		<source src="{{file}}" data-title={{title}}>

What is data-title for?

juan0tron

comment created time in 9 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

+{% block audio %}+	<audio+		class="wagtailmedia-audio"+		src="{{file}}" +		{% if mute %}muted{% endif %}+		{% if autoplay %}autoplay{% endif %}+		{% if loop %}loop{% endif %}+		controls>+	</audio>+{% endblock %}

This might be a stupid question but this project didn’t have anything like this to define the medias’ output before?

juan0tron

comment created time in 9 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

+const React = window.React;+const ReactDOM = window.ReactDOM;+const Modifier = window.DraftJS.Modifier;+const EditorState = window.DraftJS.EditorState;+const AtomicBlockUtils = window.DraftJS.AtomicBlockUtils;++/**+ *  Choose a media file in this modal+ */+class WagtailMediaChooser extends window.draftail.ModalWorkflowSource {+    componentDidMount() {+        const { onClose, entityType, entity, editorState } = this.props;++        $(document.body).on('hidden.bs.modal', this.onClose);++        this.workflow = global.ModalWorkflow({+            url: `${window.chooserUrls.mediaChooser}?select_format=true`,+            onload: MEDIA_CHOOSER_MODAL_ONLOAD_HANDLERS,+            urlParams: {},+            responses: {+                mediaChosen: (data) => this.onChosen(data)+            },+            onError: (err) => {+                console.error("WagtailMediaChooser Error", err);+                onClose();+            },+        });+    }++    onChosen(data) {+        const { editorState, entityType, onComplete } = this.props;++        const content   = editorState.getCurrentContent();+        const selection = editorState.getSelection();++        const entityData = data;+        const mutability = 'IMMUTABLE';++        const contentWithEntity = content.createEntity(entityType.type, mutability, entityData);+        const entityKey         = contentWithEntity.getLastCreatedEntityKey();+        const nextState         = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ');++        this.workflow.close();++        onComplete(nextState);+    }+}++// Constraints the maximum size of the tooltip.+const OPTIONS_MAX_WIDTH  = 300;+const OPTIONS_SPACING    = 70;+const TOOLTIP_MAX_WIDTH  = OPTIONS_MAX_WIDTH + OPTIONS_SPACING;++/**+ *	Places media thumbnail HTML in the Rich Text Editor+ */+class WagtailMediaBlock extends React.Component {+    constructor(props) {+        super(props);++        this.state = {+            showTooltipAt: null,+        };++        this.setState      = this.setState.bind(this);+        this.openTooltip   = this.openTooltip.bind(this);+        this.closeTooltip  = this.closeTooltip.bind(this);+        this.renderTooltip = this.renderTooltip.bind(this);+    }++    componentDidMount() {+        document.addEventListener('mouseup', this.closeTooltip);+        document.addEventListener('keyup', this.closeTooltip);+        window.addEventListener('resize', this.closeTooltip);+    }++    openTooltip(e) {+        const { blockProps } = this.props;+        const { entity, onRemoveEntity } = blockProps;+        const data = entity.getData();++        const trigger = e.target.closest('[data-draftail-trigger]');++        if (!trigger) return; // Click is within the tooltip++        const container = trigger.closest('[data-draftail-editor-wrapper]');++        if (container.children.length > 1) return;  // Tooltip already exists++        const containerRect = container.getBoundingClientRect();+        const rect = trigger.getBoundingClientRect();+        const maxWidth = trigger.parentNode.offsetWidth - rect.width;+        const direction = maxWidth >= TOOLTIP_MAX_WIDTH ? 'left' : 'top-left'; // Determines position of the arrow on the tooltip++        let top  = 0;+        let left = 0;++        if(direction == 'left'){+            left = rect.width + 50;+            top  = rect.top - containerRect.top + (rect.height / 2);+        }+        else if (direction == 'top-left'){+            top = rect.top - containerRect.top + rect.height;+        }++        this.setState({+            showTooltipAt: {+                container: container,+                top: top,+                left: left,+                width: rect.width,+                height: rect.height,+                direction: direction,+            }+        });+    }++    closeTooltip(e) {+        if(e.target.classList){+            if(e.target.classList.contains("Tooltip__button")){+                return; // Don't setState if the "Delete" button was clicked+            }+        }+        this.setState({ showTooltipAt: null });+    }++    /**+     * Returns either a tooltip "portal" element or null+     */+    renderTooltip(data) {+        const { showTooltipAt } = this.state;+        const { blockProps } = this.props;+        const { entity, onRemoveEntity } = blockProps;++        // No tooltip coords exist, don't show one+        if(!showTooltipAt) return null;++        let options = []+        if(data.autoplay) options.push("Autoplay");+        if(data.mute) options.push("Mute");+        if(data.loop) options.push("Loop");+        const options_str = options.length ? options.join(", ") : "";++        return ReactDOM.createPortal(React.createElement('div', null,+            React.createElement('div',+                {+                    style: {+                        top: showTooltipAt.top,+                        left: showTooltipAt.left+                    },+                    class: "Tooltip Tooltip--"+showTooltipAt.direction,+                    role:  "tooltip"+                },+                React.createElement('div', { style: { maxWidth: showTooltipAt.width } }, [+                    React.createElement('p', {+                        class: "ImageBlock__alt"+                    }, data.type.toUpperCase()+": "+data.title),+                    React.createElement('p', { class: "ImageBlock__alt" }, options_str),+                    React.createElement('button', {+                        class: "button button-secondary no Tooltip__button",+                        onClick: onRemoveEntity+                    }, "Delete")+                ])+            )+        ), showTooltipAt.container);+    }++    render() {+        const { blockProps } = this.props;+        const { entity } = blockProps;+        const data = entity.getData();++        let icon;+        if(data.type == 'video'){+            icon = React.createElement('span',  { class:"icon icon-fa-video-camera", 'aria-hidden':"true" });+        }+        else if(data.type == 'audio'){+            icon = React.createElement('span',  { class:"icon icon-fa-music", 'aria-hidden':"true" });+        }++        return React.createElement('button',+            {+                class: 'MediaBlock WagtailMediaBlock '+data.type,+                type:  'button',+                tabindex: '-1',+                'data-draftail-trigger': "true",+                onClick: this.openTooltip,+                style: { 'min-width': '100px', 'min-height': '100px'}+            },+            [+                React.createElement('span',+                    { class:"MediaBlock__icon-wrapper", 'aria-hidden': "true" },+                    React.createElement('span', {}, icon)

This doesn’t need aria-hidden if it’s already set on the icon.

juan0tron

comment created time in 9 days

Pull request review commenttorchbox/wagtailmedia

Embed media in rich text fields using Draftail

+const React = window.React;+const ReactDOM = window.ReactDOM;+const Modifier = window.DraftJS.Modifier;+const EditorState = window.DraftJS.EditorState;+const AtomicBlockUtils = window.DraftJS.AtomicBlockUtils;++/**+ *  Choose a media file in this modal+ */+class WagtailMediaChooser extends window.draftail.ModalWorkflowSource {+    componentDidMount() {+        const { onClose, entityType, entity, editorState } = this.props;++        $(document.body).on('hidden.bs.modal', this.onClose);++        this.workflow = global.ModalWorkflow({+            url: `${window.chooserUrls.mediaChooser}?select_format=true`,+            onload: MEDIA_CHOOSER_MODAL_ONLOAD_HANDLERS,+            urlParams: {},+            responses: {+                mediaChosen: (data) => this.onChosen(data)+            },+            onError: (err) => {+                console.error("WagtailMediaChooser Error", err);+                onClose();+            },+        });+    }++    onChosen(data) {+        const { editorState, entityType, onComplete } = this.props;++        const content   = editorState.getCurrentContent();+        const selection = editorState.getSelection();++        const entityData = data;+        const mutability = 'IMMUTABLE';++        const contentWithEntity = content.createEntity(entityType.type, mutability, entityData);+        const entityKey         = contentWithEntity.getLastCreatedEntityKey();+        const nextState         = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ');++        this.workflow.close();++        onComplete(nextState);+    }+}++// Constraints the maximum size of the tooltip.+const OPTIONS_MAX_WIDTH  = 300;+const OPTIONS_SPACING    = 70;+const TOOLTIP_MAX_WIDTH  = OPTIONS_MAX_WIDTH + OPTIONS_SPACING;++/**+ *	Places media thumbnail HTML in the Rich Text Editor+ */+class WagtailMediaBlock extends React.Component {+    constructor(props) {+        super(props);++        this.state = {+            showTooltipAt: null,+        };++        this.setState      = this.setState.bind(this);+        this.openTooltip   = this.openTooltip.bind(this);+        this.closeTooltip  = this.closeTooltip.bind(this);+        this.renderTooltip = this.renderTooltip.bind(this);+    }++    componentDidMount() {+        document.addEventListener('mouseup', this.closeTooltip);+        document.addEventListener('keyup', this.closeTooltip);+        window.addEventListener('resize', this.closeTooltip);+    }++    openTooltip(e) {+        const { blockProps } = this.props;+        const { entity, onRemoveEntity } = blockProps;+        const data = entity.getData();++        const trigger = e.target.closest('[data-draftail-trigger]');++        if (!trigger) return; // Click is within the tooltip++        const container = trigger.closest('[data-draftail-editor-wrapper]');++        if (container.children.length > 1) return;  // Tooltip already exists++        const containerRect = container.getBoundingClientRect();+        const rect = trigger.getBoundingClientRect();+        const maxWidth = trigger.parentNode.offsetWidth - rect.width;+        const direction = maxWidth >= TOOLTIP_MAX_WIDTH ? 'left' : 'top-left'; // Determines position of the arrow on the tooltip++        let top  = 0;+        let left = 0;++        if(direction == 'left'){+            left = rect.width + 50;+            top  = rect.top - containerRect.top + (rect.height / 2);+        }+        else if (direction == 'top-left'){+            top = rect.top - containerRect.top + rect.height;+        }++        this.setState({+            showTooltipAt: {+                container: container,+                top: top,+                left: left,+                width: rect.width,+                height: rect.height,+                direction: direction,+            }+        });+    }++    closeTooltip(e) {+        if(e.target.classList){+            if(e.target.classList.contains("Tooltip__button")){+                return; // Don't setState if the "Delete" button was clicked+            }+        }+        this.setState({ showTooltipAt: null });+    }++    /**+     * Returns either a tooltip "portal" element or null+     */+    renderTooltip(data) {+        const { showTooltipAt } = this.state;+        const { blockProps } = this.props;+        const { entity, onRemoveEntity } = blockProps;++        // No tooltip coords exist, don't show one+        if(!showTooltipAt) return null;++        let options = []+        if(data.autoplay) options.push("Autoplay");+        if(data.mute) options.push("Mute");+        if(data.loop) options.push("Loop");+        const options_str = options.length ? options.join(", ") : "";++        return ReactDOM.createPortal(React.createElement('div', null,+            React.createElement('div',+                {+                    style: {+                        top: showTooltipAt.top,+                        left: showTooltipAt.left+                    },+                    class: "Tooltip Tooltip--"+showTooltipAt.direction,+                    role:  "tooltip"+                },+                React.createElement('div', { style: { maxWidth: showTooltipAt.width } }, [+                    React.createElement('p', {+                        class: "ImageBlock__alt"+                    }, data.type.toUpperCase()+": "+data.title),+                    React.createElement('p', { class: "ImageBlock__alt" }, options_str),+                    React.createElement('button', {+                        class: "button button-secondary no Tooltip__button",+                        onClick: onRemoveEntity+                    }, "Delete")+                ])+            )+        ), showTooltipAt.container);+    }++    render() {+        const { blockProps } = this.props;+        const { entity } = blockProps;+        const data = entity.getData();++        let icon;+        if(data.type == 'video'){+            icon = React.createElement('span',  { class:"icon icon-fa-video-camera", 'aria-hidden':"true" });+        }+        else if(data.type == 'audio'){+            icon = React.createElement('span',  { class:"icon icon-fa-music", 'aria-hidden':"true" });+        }++        return React.createElement('button',+            {+                class: 'MediaBlock WagtailMediaBlock '+data.type,

Yep, it looks like we should just reuse MediaBlock.

juan0tron

comment created time in 9 days

more