aboutsummaryrefslogtreecommitdiffstats
path: root/root/research/mmmfs/examples
diff options
context:
space:
mode:
Diffstat (limited to 'root/research/mmmfs/examples')
-rw-r--r--root/research/mmmfs/examples/$order5
-rw-r--r--root/research/mmmfs/examples/gallery/$order2
-rw-r--r--root/research/mmmfs/examples/gallery/actual_image/image$png.pngbin0 -> 678429 bytes
-rw-r--r--root/research/mmmfs/examples/gallery/actual_image/preview: image$png.pngbin0 -> 31880 bytes
-rw-r--r--root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png1
-rw-r--r--root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png1
-rw-r--r--root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon19
-rw-r--r--root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon12
-rw-r--r--root/research/mmmfs/examples/gallery/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/image/URL -> image$png1
-rw-r--r--root/research/mmmfs/examples/image/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md88
-rw-r--r--root/research/mmmfs/examples/intro: text$markdown+sidenotes.md10
-rw-r--r--root/research/mmmfs/examples/language_support/$order3
-rw-r--r--root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js15
-rw-r--r--root/research/mmmfs/examples/language_support/javascript/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua9
-rw-r--r--root/research/mmmfs/examples/language_support/lua/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon10
-rw-r--r--root/research/mmmfs/examples/language_support/moonscript/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/language_support/preview: text$markdown6
-rw-r--r--root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon16
-rw-r--r--root/research/mmmfs/examples/language_support/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/markdown/text$markdown.md20
-rw-r--r--root/research/mmmfs/examples/markdown/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/pinwall/$order4
-rw-r--r--root/research/mmmfs/examples/pinwall/image/image$png.pngbin0 -> 128929 bytes
-rw-r--r--root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json1
-rw-r--r--root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon121
-rw-r--r--root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json1
-rw-r--r--root/research/mmmfs/examples/pinwall/text/text$plain.txt4
-rw-r--r--root/research/mmmfs/examples/pinwall/title: text$plain1
-rw-r--r--root/research/mmmfs/examples/pinwall/video/URL -> video$mp41
-rw-r--r--root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json1
-rw-r--r--root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video1
-rw-r--r--root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json1
-rw-r--r--root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon44
37 files changed, 405 insertions, 0 deletions
diff --git a/root/research/mmmfs/examples/$order b/root/research/mmmfs/examples/$order
new file mode 100644
index 0000000..4ee3140
--- /dev/null
+++ b/root/research/mmmfs/examples/$order
@@ -0,0 +1,5 @@
+language_support
+image
+markdown
+gallery
+pinwall
diff --git a/root/research/mmmfs/examples/gallery/$order b/root/research/mmmfs/examples/gallery/$order
new file mode 100644
index 0000000..9d438bd
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/$order
@@ -0,0 +1,2 @@
+link_to_image
+actual_image
diff --git a/root/research/mmmfs/examples/gallery/actual_image/image$png.png b/root/research/mmmfs/examples/gallery/actual_image/image$png.png
new file mode 100644
index 0000000..b499413
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/actual_image/image$png.png
Binary files differ
diff --git a/root/research/mmmfs/examples/gallery/actual_image/preview: image$png.png b/root/research/mmmfs/examples/gallery/actual_image/preview: image$png.png
new file mode 100644
index 0000000..f9dbfad
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/actual_image/preview: image$png.png
Binary files differ
diff --git a/root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png b/root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png
new file mode 100644
index 0000000..7cf76ff
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png
@@ -0,0 +1 @@
+https://picsum.photos/600/600/?image=101
diff --git a/root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png b/root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png
new file mode 100644
index 0000000..2b2233b
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png
@@ -0,0 +1 @@
+https://picsum.photos/200/200/?image=101
diff --git a/root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon b/root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon
new file mode 100644
index 0000000..0178ac2
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon
@@ -0,0 +1,19 @@
+import ReactiveVar, text, elements from require 'mmm.component'
+import div, a, img from elements
+
+=>
+ index = ReactiveVar 1
+
+ prev = (i) -> math.max 1, i - 1
+ next = (i) -> math.min #@children, i + 1
+
+ div {
+ div {
+ a 'prev', href: '#', onclick: -> index\transform prev
+ index\map (i) -> text " image ##{i} "
+ a 'next', href: '#', onclick: -> index\transform next
+ },
+ index\map (i) ->
+ child = assert @children[i], "image not found!"
+ img src: @children[i]\gett 'URL -> image/png'
+ }
diff --git a/root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..9bdac54
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,12 @@
+import div, h1, a, img, br from require 'mmm.dom'
+
+=>
+ link = (child) -> a {
+ href: '#',
+ onclick: -> BROWSER\navigate child.path
+ img src: child\gett 'preview', 'URL -> image/png'
+ }
+
+ content = [link child for child in *@children]
+ table.insert content, 1, h1 'gallery index'
+ div content
diff --git a/root/research/mmmfs/examples/gallery/title: text$plain b/root/research/mmmfs/examples/gallery/title: text$plain
new file mode 100644
index 0000000..2e9ef34
--- /dev/null
+++ b/root/research/mmmfs/examples/gallery/title: text$plain
@@ -0,0 +1 @@
+a gallery of images
diff --git a/root/research/mmmfs/examples/image/URL -> image$png b/root/research/mmmfs/examples/image/URL -> image$png
new file mode 100644
index 0000000..c586722
--- /dev/null
+++ b/root/research/mmmfs/examples/image/URL -> image$png
@@ -0,0 +1 @@
+https://picsum.photos/200?random
diff --git a/root/research/mmmfs/examples/image/title: text$plain b/root/research/mmmfs/examples/image/title: text$plain
new file mode 100644
index 0000000..dca924f
--- /dev/null
+++ b/root/research/mmmfs/examples/image/title: text$plain
@@ -0,0 +1 @@
+link to a remote image
diff --git a/root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md b/root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md
new file mode 100644
index 0000000..8a6a185
--- /dev/null
+++ b/root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md
@@ -0,0 +1,88 @@
+## 6.1 publishing and blogging
+### 6.1.1 blogging
+Blogging is pretty straightforward since it generally just involves publishing lightly-formatted text,
+interspersed with media such as images and videos or perhaps social media posts.
+Markdown is a great tool for this job, and has been integrated into the system to much success:
+There are two different types registered with *converts*: `text/markdown` and `text/markdown+span`.
+They both render to HTML (and DOM nodes), so they are immediately viewable as part of the system.
+The only difference for `text/markdown+span` is that it is limited to a single line,
+and doesn't render as a paragraph but rather just a line of text.
+This makes it suitable for denoting formatted-text titles and other small strings of text.
+
+The problem of embedding other content together with text comfortably is also solved easily
+because Markdown allows embedding arbitrary HTML in the document.
+This made it possible to define a set of pseudo-HTML elements in the Markdown-convert,
+`<mmm-embed>` and `<mmm-link>`, which respectively embed and link to other content native to mmmfs.
+
+### 6.1.2&emsp;academic publishing
+<div class="sidenote" style="margin-top: 1.25rem">
+One of the 'standard' solutions, <a href="https://www.latex-project.org/">LaTeX</a>,
+is arguably at least as complex as the mmm system proposed here, but has a much narrower scope,
+since it does not support interaction.
+</div>
+
+Academic publishing is notoriously complex, involving not only the transclusion of diagrams
+and other media but generally requiring precise and consistent control over formatting and layout.
+Some of these complexities are tedious to manage but present good opportunities for programmatic
+systems and media to do work for the writer.
+
+One such topic is the topic of references.
+References appear in various formats at multiple positions in an academic document;
+usually, they are referenced via a reduced visual form within the text of the document
+and then shown again with full details at the end of the document.
+
+For the sake of this thesis, referencing has been implemented using a subset of the popular
+BibTeX format for describing citations. Converts have been implemented for the `text/bibtex`
+type to convert to a full reference format (to `mmm/dom`) and to an inline side-note reference
+(`mmm/dom+link`) that can be transcluded using the `<mmm-link>` pseudo-tag.
+
+For convenience, a convert from the `URL -> cite/acm` type has been provided to `URL -> text/bibtex`,
+which generates links to the ACM Digital Library<mmm-embed path="../references/acm-dl" wrap="sidenote"></mmm-embed>
+API for accessing BibTeX citations for documents in the library. This means that it is enough to store the link to the
+ACM DL entry in mmmfs, and the reference will automatically be fetched, and therefore stay up to date with potential
+remote corrections.
+
+## 6.2&emsp;pinwall
+In many situations, and particularly for creative work, it is often useful to compile resources of
+different types for reference or inspiration and arrange them spatially so that they can be viewed
+at a glance or organized into different contexts, etc.
+Such a pinwall could serve for example to organize references to articles,
+to collect visual inspiration for a mood board, etc.
+
+As a collection, the Pinwall is primarily mapped to a Fileder in the system.
+Any content that is placed within can then be rendered by the Pinwall,
+which can constrain every piece of content to a rectangular piece on its canvas.
+This is possible through a simple script, e.g. of the type `text/moonscript -> fn -> mmm/dom`,
+which enumerates the list of children, wraps each in such a rectangular container
+and outputs the list of containers as DOM elements.
+
+The position and size of each panel are stored in an ad-hoc facet, encoded in the JSON data format:
+`pinwall_info: text/json`. Such a facet is set on each child and read whenever the script is called
+to render the children, plugging the values within the facet into the visual styling of the document.
+
+The script can also set event handlers that react to user input while the document is loaded,
+and allow the user to reposition and resize the individual pinwall items by clicking and dragging
+on the upper border or lower right-hand corner respectively.
+Whenever a change is made the event handler can then update the value in the `pinwall_info` facet,
+so that the updated position and size are stored for the next time the pinwall is opened.
+
+## 6.3&emsp;slideshow
+Another common use of digital documents is as aids in a verbal presentation.
+These often take the form of slideshows, for the creation of which a number of established applications exist.
+In simple terms, a slideshow is simply a linear series of screen-sized documents, that can be
+advanced (and rewound) one by one using keypresses.
+
+The implementation of this is rather straightforward as well.
+The slideshow as a whole becomes a fileder with a script that generates a designated viewport rectangle,
+as well as a control interface with keys for advancing the active slide.
+It also allows putting the browser into fullscreen mode to maximize screen space and remove visual elements
+of the website that may distract from the presentation, and register an event handler for keyboard accelerators
+for moving through the presentation.
+
+Finally, the script simply embeds the first of its child-fileders into the viewport rectangle.
+Once the current slide is changed, the next embedded child is simply chosen.
+
+<!--
+## code documentation
+/meta/mmm.dom/:%20text/html+interactive
+-->
diff --git a/root/research/mmmfs/examples/intro: text$markdown+sidenotes.md b/root/research/mmmfs/examples/intro: text$markdown+sidenotes.md
new file mode 100644
index 0000000..126f407
--- /dev/null
+++ b/root/research/mmmfs/examples/intro: text$markdown+sidenotes.md
@@ -0,0 +1,10 @@
+# 6&emsp;example use-cases
+To illustrate the capabilities of the proposed system, and to compare the results with the framework introduced above,
+a number of example use cases have been chosen and implemented from the perspective of a user.
+In the following section I will introduce these use cases and briefly summarize the implementation
+approach in terms of the capabilities of the proposed system.
+
+<div style="break-before: page;"></div>
+
+<span class="sidenote">The online version is available at [s-ol.nu/ba](https://s-ol.nu/ba).</span>
+The following examples can be viewed and inspected in the interactive version online:
diff --git a/root/research/mmmfs/examples/language_support/$order b/root/research/mmmfs/examples/language_support/$order
new file mode 100644
index 0000000..3cc0e47
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/$order
@@ -0,0 +1,3 @@
+javascript
+moonscript
+lua
diff --git a/root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js b/root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js
new file mode 100644
index 0000000..de56531
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js
@@ -0,0 +1,15 @@
+const e = (elem, children) => {
+ const node = document.createElement(elem);
+
+ if (typeof children === 'string')
+ node.innerText = children;
+ else
+ children.forEach(child => node.appendChild(child));
+
+ return node;
+};
+
+return e('article', [
+ e('h1', 'JavaScript'),
+ e('p', 'JavaScript is supported natively in the browser but is not currently pre-rendered on the server.'),
+]);
diff --git a/root/research/mmmfs/examples/language_support/javascript/title: text$plain b/root/research/mmmfs/examples/language_support/javascript/title: text$plain
new file mode 100644
index 0000000..581fbc7
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/javascript/title: text$plain
@@ -0,0 +1 @@
+JavaScript
diff --git a/root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua b/root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua
new file mode 100644
index 0000000..62e79f1
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua
@@ -0,0 +1,9 @@
+local d = require 'mmm.dom'
+
+local lua = d.a { 'Lua', href = 'https://www.lua.org/' }
+local fengari = d.a { 'fengari.io', href = 'https://fengari.io/' }
+
+return d.article {
+ d.h1 'Lua',
+ d.p { lua, ' is fully supported using ', fengari, ' on the Client.' }
+}
diff --git a/root/research/mmmfs/examples/language_support/lua/title: text$plain b/root/research/mmmfs/examples/language_support/lua/title: text$plain
new file mode 100644
index 0000000..0f9d550
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/lua/title: text$plain
@@ -0,0 +1 @@
+Lua
diff --git a/root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon b/root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon
new file mode 100644
index 0000000..5cc50e6
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon
@@ -0,0 +1,10 @@
+import a, article, h1, p from require 'mmm.dom'
+
+moonscript = a 'MoonScript', href: 'https://moonscript.org/'
+lua = a 'Lua', href: 'https://www.lua.org/'
+fengari = a 'fengari.io', href: 'https://fengari.io/'
+
+article {
+ h1 'MoonScript',
+ p moonscript, " is compiled to ", lua, " on the server, which is then executed on the client using ", fengari, "."
+}
diff --git a/root/research/mmmfs/examples/language_support/moonscript/title: text$plain b/root/research/mmmfs/examples/language_support/moonscript/title: text$plain
new file mode 100644
index 0000000..f8871ac
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/moonscript/title: text$plain
@@ -0,0 +1 @@
+MoonScript
diff --git a/root/research/mmmfs/examples/language_support/preview: text$markdown b/root/research/mmmfs/examples/language_support/preview: text$markdown
new file mode 100644
index 0000000..d6c2845
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/preview: text$markdown
@@ -0,0 +1,6 @@
+this Fileder contains some minimal examples showing support for various languages `mmmfs` supports currently.
+
+Language support is mostly limited by the fact that `mmmfs` currently targets web browsers,
+on the server any scripting language that can be executed can theoretically be integrated with minimal effort.
+
+Using the inspector mode to view the source of the Fileders below is encouraged.
diff --git a/root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..4ae0679
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,16 @@
+import article, h1, p, ul, li, a from require 'mmm.dom'
+
+single = (a) -> a
+
+=>
+ children = for child in *@children
+ title = child\gett 'title: text/plain'
+ li a title, href: child.path, onclick: (e) =>
+ e\preventDefault!
+ BROWSER\navigate child.path
+
+ article {
+ h1 single @gett 'title: text/plain'
+ p single @gett 'preview: mmm/dom'
+ ul children
+ }
diff --git a/root/research/mmmfs/examples/language_support/title: text$plain b/root/research/mmmfs/examples/language_support/title: text$plain
new file mode 100644
index 0000000..ae06474
--- /dev/null
+++ b/root/research/mmmfs/examples/language_support/title: text$plain
@@ -0,0 +1 @@
+scripting language support
diff --git a/root/research/mmmfs/examples/markdown/text$markdown.md b/root/research/mmmfs/examples/markdown/text$markdown.md
new file mode 100644
index 0000000..880eedb
--- /dev/null
+++ b/root/research/mmmfs/examples/markdown/text$markdown.md
@@ -0,0 +1,20 @@
+This is a markdown document rendered using [marked][marked] on the client, and [discount][discount] on the server.
+All Markdown features are supported, for example there is support for lists...
+
+- a list of things
+- (two things)
+
+...and syntax-highlighted code tags:
+
+```
+print "Hello World"
+```
+
+Since Markdown supports inline HTML, mmmfs shorthands can also be used to embed and reference content from elsewhere in
+the system. For example, the title of this fileder can be embedded using
+`<mmm-embed facet="title"></mmm-embed>`:
+
+<mmm-embed facet="title"></mmm-embed>
+
+[marked]: https://marked.js.org/
+[discount]: https://luarocks.org/modules/craigb/discount
diff --git a/root/research/mmmfs/examples/markdown/title: text$plain b/root/research/mmmfs/examples/markdown/title: text$plain
new file mode 100644
index 0000000..7915148
--- /dev/null
+++ b/root/research/mmmfs/examples/markdown/title: text$plain
@@ -0,0 +1 @@
+markdown content
diff --git a/root/research/mmmfs/examples/pinwall/$order b/root/research/mmmfs/examples/pinwall/$order
new file mode 100644
index 0000000..4a12798
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/$order
@@ -0,0 +1,4 @@
+image
+text
+video
+youtube_video
diff --git a/root/research/mmmfs/examples/pinwall/image/image$png.png b/root/research/mmmfs/examples/pinwall/image/image$png.png
new file mode 100644
index 0000000..1628d99
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/image/image$png.png
Binary files differ
diff --git a/root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json
new file mode 100644
index 0000000..7149346
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 117.0, "y": 592.0, "w": 403.0, "h": 296.0} \ No newline at end of file
diff --git a/root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..90822f2
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,121 @@
+import article, div from require 'mmm.dom'
+import convert from require 'mmm.mmmfs.conversion'
+
+update_info = (fileder, x, y, w, h) ->
+ info = (fileder\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300
+ info.x = x if x
+ info.y = y if y
+ info.w = w if w
+ info.h = h if h
+
+ json = convert 'table', 'text/json', info, fileder, 'pinwall_info'
+ fileder\set 'pinwall_info: text/json', json
+
+CLIENT = MODE == 'CLIENT'
+
+=>
+
+ pending = {}
+ observe = if CLIENT
+ map = {}
+ observer = js.new js.global.ResizeObserver, (_, entries) ->
+ for entry in js.of entries
+ if child = map[entry.target]
+ rect = entry.contentRect
+ pending[child] = -> update_info child, nil, nil, rect.width, rect.height
+
+ (node, child) ->
+ map[node] = child
+ observer\observe node
+
+ drag = nil
+
+ children = for child in *@children
+ info = (child\get 'pinwall_info: table') or x: 100, y: 100, w: 560, h: 315
+
+ wrapper = div {
+ style:
+ position: 'absolute'
+ padding: '10px'
+ resize: 'both'
+ overflow: 'hidden'
+ background: 'var(--gray-dark)'
+ border: '1px solid var(--gray-bright)'
+
+ left: "#{info.x}px"
+ top: "#{info.y}px"
+ width: "#{info.w}px"
+ height: "#{info.h}px"
+
+ -- handle for moving the child
+ div {
+ style:
+ top: '0'
+ left: '0'
+ right: '0'
+ height: '10px'
+ cursor: 'pointer'
+ position: 'absolute'
+
+ onmousedown: CLIENT and (_, e) ->
+ node = e.target.parentElement
+ drag = {
+ :child
+ :node
+
+ startX: tonumber node.style.left\match '(%d+)px'
+ startY: tonumber node.style.top\match '(%d+)px'
+ startMouseX: e.clientX
+ startMouseY: e.clientY
+ }
+ }
+
+ -- child content
+ div {
+ style:
+ width: '100%'
+ height: '100%'
+ background: 'var(--white)'
+
+ (child\get 'mmm/dom') or div '(unrenderable)'
+ }
+ }
+
+ -- listen for resize events
+ observe wrapper, child if CLIENT
+ wrapper
+
+ children.style = {
+ width: '1000px'
+ height: '500px'
+ }
+
+ if CLIENT
+ children.onmousemove = (_, e) ->
+ return unless drag
+
+ x = drag.startX + (e.clientX - drag.startMouseX)
+ y = drag.startY + (e.clientY - drag.startMouseY)
+ drag.node.style.left = "#{x}px"
+ drag.node.style.top = "#{y}px"
+
+ children.onmouseup = (_, e) ->
+ for k, func in pairs pending
+ func!
+ pending = {}
+
+ return unless drag
+
+ x = drag.startX + (e.clientX - drag.startMouseX)
+ y = drag.startY + (e.clientY - drag.startMouseY)
+ update_info drag.child, x, y
+ drag = nil
+
+ children.onmouseleave = (_, e) ->
+ return unless drag
+
+ drag.node.style.left = "#{drag.startX}px"
+ drag.node.style.top = "#{drag.startY}px"
+ drag = nil
+
+ article children
diff --git a/root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json
new file mode 100644
index 0000000..07a9448
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 28.0, "y": 179.0, "w": 1457.0, "h": 246.0} \ No newline at end of file
diff --git a/root/research/mmmfs/examples/pinwall/text/text$plain.txt b/root/research/mmmfs/examples/pinwall/text/text$plain.txt
new file mode 100644
index 0000000..8838e5a
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/text/text$plain.txt
@@ -0,0 +1,4 @@
+This is a pinwall example.
+Every box is a separate fileder.
+The boxes can be rearranged and resized freely.
+If the server is in read-write mode, the changes are saved persistently in real time.
diff --git a/root/research/mmmfs/examples/pinwall/title: text$plain b/root/research/mmmfs/examples/pinwall/title: text$plain
new file mode 100644
index 0000000..c629992
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/title: text$plain
@@ -0,0 +1 @@
+a pinwall
diff --git a/root/research/mmmfs/examples/pinwall/video/URL -> video$mp4 b/root/research/mmmfs/examples/pinwall/video/URL -> video$mp4
new file mode 100644
index 0000000..6364771
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/video/URL -> video$mp4
@@ -0,0 +1 @@
+https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_480_1_5MG.mp4
diff --git a/root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json
new file mode 100644
index 0000000..fefad32
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 1247.0, "y": 643.0, "w": 483.0, "h": 272.0} \ No newline at end of file
diff --git a/root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video b/root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video
new file mode 100644
index 0000000..7552ebe
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=ZXqgFb1U7q0 \ No newline at end of file
diff --git a/root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json
new file mode 100644
index 0000000..3e145f1
--- /dev/null
+++ b/root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json
@@ -0,0 +1 @@
+{"x": 391.0, "y": 238.0, "w": 560.0, "h": 315.0} \ No newline at end of file
diff --git a/root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..2988f29
--- /dev/null
+++ b/root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,44 @@
+-- main content
+-- doesn't have a name prefix (e.g. preview: fn -> mmm/dom)
+-- uses the 'fn ->' conversion to execute the lua function on @get
+-- resolves to a value of type mmm/dom
+=>
+ html = require 'mmm.dom'
+ import h4, div, a, span, ul, li from html
+ import link_to from (require 'mmm.mmmfs.util') html
+
+ -- render a preview block
+ preview = (child) ->
+ -- get 'title' as 'text/plain' (error if no value or conversion possible)
+ title = child\gett 'title', 'text/plain'
+
+ -- get 'preview' as a DOM description (nil if no value or conversion possible)
+ -- content = child\get 'preview', 'mmm/dom'
+
+ -- div {
+ -- h4 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path
+ -- content or span '(no renderable content)', style: { color: 'red' },
+ -- style: {
+ -- display: 'inline-block',
+ -- width: '300px',
+ -- height: '200px',
+ -- padding: '4px',
+ -- margin: '8px',
+ -- border: '4px solid #eeeeee',
+ -- overflow: 'hidden',
+ -- },
+ -- }
+
+ li link_to child
+
+ examples = ul for child in *@children
+ preview child
+
+ div {
+ style:
+ 'break-after': 'page'
+
+ (@gett 'intro: mmm/dom')
+ examples
+ (@gett 'implementation: mmm/dom')
+ }