Git Product home page Git Product logo

unpoly's Introduction

Progressive enhancement for HTML

Unpoly enhances your HTML with attributes to build dynamic UI on the server.

Unpoly works with any language or framework. It plays nice with existing code, and gracefully degrades without JavaScript.

This branch tracks the current major version, Unpoly 3.x.
If you're using Unpoly 2.x, use the 2.x-stable branch.
If you're using Unpoly 1.x or 0.x, use the 1.x-stable branch.

Getting started

Development

Installing development dependencies

To build Unpoly you require Node.js, Webpack and other npm packages.

Install the Node version from .nvmrc.

To install Webpack and other required npm packages, run:

npm install

Quick start

The following will build the library and open a web browser with the test suite:

npm run dev

To run individual tasks instead, see below.

Building the library

Tests don't consume the sources directly, but from a transpiled build in dist/.

To make fresh build, run:

npm run build-dev

This will build transpiled files such as:

dist/unpoly.js
dist/unpoly.css
dist/unpoly-migrate.js
dist/jasmine.js
dist/specs.js

There is also a task npm run build for a production build. This does not build files for testing, but also outputs minified versions.

Watching files for changes

During development it is impractical to make a full build after every change. Instead it is recommend to watch the project:

npm run watch-dev

This will make a fresh build and then watch the project for changes to the source files. When a source changes, affected build files are automatically recompiled. The incremental recompilation is much faster than a full build.

Running tests

Tests run using a browser-based Jasmine runner.

To start a web server serving the Jasmine runner:

npm run test

This will open a server on http://localhost:4000 and opens that URL with your default browser.

In addition to the unit tests, there is an optional support repo unpoly-manual-tests. It contains a Rails app to play with Unpoly features that are hard to test well with a unit test. E.g. the visual look of overlays, or edge cases when booting Unpoly.

Making a new release

You can use this repository to publish a new version of the unpoly npm package.

The release process currently requires Ruby. To install these dependencies:

  • Install the Ruby version from .ruby-version
  • Run bundle install

There is a guided CLI interface to lead you through the release process. To start the process run:

bundle exec rake release:process

Credits

unpoly's People

Contributors

adam12 avatar apollo13 avatar christopherfritz avatar codener avatar dastra-mak avatar denzelem avatar dr4k4n avatar dthomas avatar foobear avatar hfjallemark avatar iaddict avatar jakobscholz avatar jiegillet avatar jmoppel avatar kd6-3 avatar kratob avatar ktec avatar marcus-at-localhost avatar mfazekas avatar mordae avatar mschoettle avatar naapperas avatar niklas-hasselmeyer avatar pfw avatar ralfclaassens avatar ro31337 avatar robinvdvleuten avatar stefanfisk avatar sztheory avatar triskweline avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unpoly's Issues

Deprecate .css.scss and .css.sass extensions in sass-rails 5.x

DEPRECATION WARNING: Extra .css in SASS file is unnecessary. Rename unpoly-rails-0.29.0/lib/assets/stylesheets/unpoly.css.sass to unpoly-rails-0.29.0/lib/assets/stylesheets/unpoly.sass.

DEPRECATION WARNING: Extra .css in SASS file is unnecessary. Rename unpoly-rails-0.29.0/lib/assets/stylesheets/unpoly-bootstrap3.css.sass to unpoly-rails-0.29.0/lib/assets/stylesheets/unpoly-bootstrap3.sass.

https://github.com/rails/sass-rails/blob/5-0-stable/lib/sass/rails/importer.rb#L123

Browser history not updating after form post to ASP.NET Core backend.

Hey,

I have a standard HTML form tag:

<form method="post" up-target="body" action="/login">
 ...
</form>

And an ASP.NET Core backend controller that processes the request and redirects to the homepage (GET request):

public async Task<IActionResult> Login(Login.Command command)
{
    Log.ForContext<AuthenticationController>().Information($"Attempting login: {command.Email}");
    await _mediator.Send(command);
    return Redirect("/");
}

As expected the form is submitted via AJAX, and the body content is replaced with the home page on successful login. However, the browser history doesn't update, i.e. the URL remains on "/login".

According to the docs, this should just work based on the redirection to a GET request. Dev tools is showing what I'd expect it to see:

image

I also followed the server protocols section of the docs and added a middleware to add the recommended headers on 302 redirects:

app.Use(next =>
{
    return async context =>
    {
        await next(context);

        if (context.Response.StatusCode == StatusCodes.Status302Found)
        {
            context.Response.Headers.Add("X-Up-Method", "GET");
            context.Response.Headers.Add("X-Up-Location", context.Response.Headers["Location"]);
        }
    };
});

Which sets the headers appropriately:

image

But still no history updates!

I've tried using different Redirect methods on the server in case it made a difference, i.e. straight "Redirect("/")" as well as ASP.NET Core helpers for redirecting to actions - "RedirectToAction("Login")". Everything else is working fine, page fragment updates from links, opening pages in modals etc etc.

Any suggestions on what I'm doing wrong?

Cheers!

Modal flicker

First off, thanks for Unpoly - it's been a joy to use thus far.

I'm dealing with a strange flickering issue with Unpoly modals, and originally I thought it was related to other project CSS, but I can reproduce it without any other stylesheets loaded, which makes me believe it's more specific to Unpoly.

I've included a video demonstrating this - has anybody seen this before?

http://adamdaniels.ca/i/screencast_2017-03-03_16-40-01.mp4

Back button won't trigger destructors

Using the back button does not trigger destructors.

Since compilers would need to clean up event listeners bound to other elements (like document), they can not do that. The compiler will be re-initialized and re-register its event listener a second time.

Example files can be found here: https://gist.github.com/foobear/a9b2b2a678cdd948e934c0e61138a5b6

The example above was tested in Chrome 60 and Firefox 54.
I'm currently binding events to $('body') to work around the issue; the body tag is replaced when going back.

Use of eval

Added unpoly directly to my bundler however it is failing minification due to use of eval in multiple scopes, thus it is not able to minimize properly.

The eval's are all of the form of:

knife: eval(typeof Knife !== "undefined" && Knife !== null ? Knife.point : void 0),

8 of them specifically.

There is no Knife defined anywhere in the output code nor does the knife in the returned object seem to be used anywhere in the output code. It does not seem to be referenced in the documentation anywhere either.

What is the point of knife or Knife in the dist code as it does not seem to be used in any form, and could it be removed in the distributed code as the eval's are wrecking havoc with minification.

Prevent stripping trailing slash

Hello, I'm giving unpoly a test ride on a Django application, so far, so good.
Except that it strips the trailing slash by default, how can I set the stripTrailingSlash to false by default?

Unpoly isn't parsing boolean attributes properly

I'm using some html generation libraries that generate boolean attributes using the k=k format. According to this, it seems that boolean attributes should be parseable in a few ways that are considered equivalent:

http://w3c.github.io/html/infrastructure.html#sec-boolean-attributes

I have a library that is producing this format:

<div up-keep="up-keep"> 

This should be recognized as boolean inclusion of up-keep but it seems that unpoly fails to pick it up.

I understand the brevity argument from #11 but this is generated markup, so brevity isn't important and the output format isn't configurable, unfortunately.

Update history after up.submit() with POST

I can't get the browser history to update after up.submit() with POST.

[options.history=true]
Successful form submissions will add a history entry and change the browser's location bar if the form either uses the GET method or the response redirected to another page (this requires the unpoly-rails gem). If you want to prevent history changes in any case, set this to false. If you pass a String, it is used as the URL for the browser history.

I'm not using the unpoly-rails gem, but reading http://unpoly.com/up.protocol#redirect-detection it seems it should be possible to do this by simply responding with a header: X-Up-Location: /current-url.

Looking through the source code it seems that only GET-requests are supported (I might be looking at the wrong place though): https://github.com/unpoly/unpoly/blob/master/lib/assets/javascripts/unpoly/dom.coffee#L282

How to change browser url with redirect after form submission?

I'm setting the response header to X-Up-Location while sending the redirect page, but the browser url is not changed. How do I achieve this behavior ?

//Spring code
@GetMapping("/expert-types")
	public String viewPage(WebRequest request, HttpServletResponse response) {
		response.setHeader("X-Up-Location", request.getContextPath() + "/expert-types");
		return "expert-types.html";
	}

@PostMapping("save-expert-type")
public String update(ExpertType entity) {
//Do db save here
return "redirect:/expert-types";
}

But the url still remains at contextPath/edit-expert-type?id=1

up-switch ignored when isSupported is false

I've ran into this a few times, and I'm not sure if it's specific to my implementation of the server protocol or just the way it is, but curious if we can work around it somehow.

Every once in a while, isSupported is false, due to up.protocol.initialRequestMethod() === 'get' being false inside canPushState.

When this happens, my use of up-switch is ignored, as Unpoly doesn't boot.

I've compared my implementation of the server protocol with the official Rails one, and it looks accurate, so I'm thinking it's more likely somewhere in Unpoly that needs to be tweaked. Perhaps we could have a separate conditional that's used only for view-state, and not related to XHR?

Thanks again for Unpoly - a huge joy to use :)

up-delay not working

I'm coding a search form for one of my websites using unpoly. The search input looks like this:

<input up-autosubmit="up-autosubmit" up-delay="200" class="form-control js-search" id="shop_name" name="shop_name" placeholder="Shop Name Here..." type="search" value="">

The problem is that up-delay doesn't seem to work, or at least not as I think it should. I thought that up-delay="200" means wait 200 miliseconds and the send the form again, or something like this. The problem is that it is still sending too many requests to the server. I've gave it different values like 100, 200, 5000, 10000, 20000 and in all cases it behaved mostly the same way. Actually up-delay="20000" should have waited 20 seconds until submiting the form but it did not, it send the request immediately, actually it sent multiple requests.

If I typed amazon in the input it would send requests with a, am, amaz, amazon as parameters. I don't think it should work like this.

Undefined method `menu_lists' in rubydoc documentation

In the sidebar of http://www.rubydoc.info/github/unpoly/unpoly/master there is currently the following stacktrace visible:

undefined method `menu_lists' for #<Object:0x007f279691c1b0>
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/templates/default/fulldoc/html/setup.rb:108:in `menu_lists'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/templates/default/fulldoc/html/full_list.erb:24:in `_erb_cache_0'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/templates/template.rb:287:in `erb'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/templates/default/fulldoc/html/setup.rb:166:in `generate_list_contents'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/templates/default/fulldoc/html/setup.rb:152:in `generate_class_list'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/commands/list_command.rb:16:in `run'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/commands/base.rb:97:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/commands/library_command.rb:74:in `block in call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/commands/library_command.rb:91:in `call_without_fork'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/commands/library_command.rb:74:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/router.rb:159:in `route_list'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/router.rb:116:in `route'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/router.rb:56:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/bundler/gems/yard-03515a8d25ad/lib/yard/server/rack_adapter.rb:52:in `call'
/home/app/rubydoc.info/app.rb:358:in `block in <class:DocServer>'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1540:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1540:in `block in compile!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:950:in `block (3 levels) in route!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:966:in `route_eval'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:950:in `block (2 levels) in route!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:987:in `block in process_route'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:985:in `catch'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:985:in `process_route'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:948:in `block in route!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:947:in `each'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:947:in `route!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1059:in `block in dispatch!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1041:in `block in invoke'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1041:in `catch'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1041:in `invoke'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1056:in `dispatch!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:882:in `block in call!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1041:in `block in invoke'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1041:in `catch'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1041:in `invoke'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:882:in `call!'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:870:in `call'
/home/app/rubydoc.info/app.rb:29:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/head.rb:13:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/conditionalget.rb:25:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.0/lib/rack/protection/xss_header.rb:18:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.0/lib/rack/protection/path_traversal.rb:16:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.0/lib/rack/protection/json_csrf.rb:18:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.0/lib/rack/protection/base.rb:49:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.0/lib/rack/protection/base.rb:49:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-protection-1.5.0/lib/rack/protection/frame_options.rb:31:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/logger.rb:15:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/commonlogger.rb:33:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:212:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:205:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/rack-1.6.4/lib/rack/head.rb:13:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:175:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1949:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1449:in `block in call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1724:in `synchronize'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1724:in `synchronize'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/sinatra-1.4.3/lib/sinatra/base.rb:1449:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/puma-3.4.0/lib/puma/configuration.rb:224:in `call'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/puma-3.4.0/lib/puma/server.rb:569:in `handle_request'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/puma-3.4.0/lib/puma/server.rb:406:in `process_client'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/puma-3.4.0/lib/puma/server.rb:271:in `block in run'
/home/app/rubydoc.info/vendor/bundle/ruby/2.3.0/gems/puma-3.4.0/lib/puma/thread_pool.rb:114:in `block in spawn_thread'

up-follow does not replace body in v0.51.0

After upgrading to from v0.50.2 to v0.51.0 links with up-follow don't replace the body anymore.

The console log looks right, but the body is not updated.

[UP] Booting framework (up:framework:boot)
unpoly.min.js:2:1126
 __ _____  ___  ___  / /_ __
/ // / _ \/ _ \/ _ \/ / // /  0.51.0
\___/_//_/ .__/\___/_/\_. / 
        / /            / /

Call `up.log.disable()` to disable logging for this session.
unpoly.min.js:2:1126
[UP] Framework booted (up:framework:booted)
unpoly.min.js:2:1126
[UP] Booting user application (up:app:boot)
unpoly.min.js:2:1126
[UP] Compiling fragment  
<body style="height: 100%; margin-top: 8em;" up-source="http://localhost:8080/blog_page.html">
unpoly.min.js:2:1126
[UP] Inserted fragment  
<body style="height: 100%; margin-top: 8em;" up-source="http://localhost:8080/blog_page.html">
  (up:fragment:inserted ( 
Object { origin: undefined }
 ))
unpoly.min.js:2:1126
[UP] User application booted (up:app:booted)
unpoly.min.js:2:1126
[UP] Loading GET http://localhost:8080/uebermedien.html (up:proxy:load ( 
Object { request: {…} }
 ))
unpoly.min.js:2:1126
[UP] Server responded with HTTP 200 (58351 bytes) (up:proxy:loaded ( 
Object { request: {…}, response: {…} }
 ))
unpoly.min.js:2:1126
[UP] Extracting body from 58351 bytes of HTML
unpoly.min.js:2:1126
[UP] Adding history entry for http://localhost:8080/uebermedien.html (up:history:push ( 
Object { url: "http://localhost:8080/uebermedien.html" }
 ))
unpoly.min.js:2:1126
[UP] Advanced to location http://localhost:8080/uebermedien.html (up:history:pushed ( 
Object { url: "http://localhost:8080/uebermedien.html" }
 ))
unpoly.min.js:2:1126
[UP] Updating body
unpoly.min.js:2:1126
```

Ability to Cancel Pending XHR Requests?

Say you're making a type-ahead search field which uses up.replace to grab a results fragment, as the user types.

I've debounced and throttled the call to up.replace but there are still some scenarios where requests might start stacking up. (when the server takes longer than expected, or network conditions change, for example)

Is there any way to cancel all pending XHR requests? or at least to clear the current proxy queue prior to firing off the next request?

I've tried tweaking up.proxy.maxRequests but it's not quite what i need.
I thought up.proxy.clear() might be what i'm looking for, but that just clears cached results

maybe i need to add my own queue layer to prevent sending multiple requests when one is still outstanding. but ideally i'd like to just be able to cancel/supercede a given request that was taking too long and just say "never mind, user changed their mind anyway, load this instead now..."

Any help would be much appreciated, thanks.

How to compile $.xxx plugins

How can I use up.compiler with plugins which directly invoke the $ symbol (example, $.validate() ) without using any selector ?

Support for IE 9

I'm loving unpoly. I'm primarily a server side developer and unpoly has brought back to me the joy of web programming. Now I can use any of the open source css libraries to build beautiful and functional UIs without having to wrap my head around all the new <insert_cool_js> libraries. I understand that unpoly does not boot for IE9 and below and I may have to fall back to jquery to init jquery plugins. Would I have to maintain two binding files for all jquery plugins I use - one with unpoly binding and another with standard jquery binding to initialize components or is there a way to achieve this in a single file as a fallback ? I apologize if I'm supposed to post this query in another forum. I couldn't find any other link. Are you active on stackoverflow ? Thanks, again for your effort with unpoly.

Unpoly 0.53.0 raises `Uncaught (in promise)`

I upgraded unpoly from 0.50.2 to 0.53.0. Now I see the following exception when having a POST request with status code 422:

// this is a normal console log
POST http://localhost:300/new 422 (Unprocessable Entity)

// this is the new exception
Uncaught (in promise) new:1

Ajax Headers possibly broken in 0.50.0

First off, fantastic library, I'm really enjoying using unpoly and has helped save tons of time in my project.

I upgraded from 0.37.0 to 0.50.0 and my AJAX requests stopped working, specifically I'm getting a CSRF token invalid when I upgrade.

var csrf = document.querySelector("meta[name=csrf-token]").content

up.ajax('pathtomyaction', {
  headers: {
    "x-csrf-token": csrf
  },
   method: 'PATCH',
   data: {
     // data
   }
})

Do I need to change the way I'm passing headers in 0.50.0?

Compiler destructors not called on up-follow

I just noticed that my compiler destructors are not being called on <a> elements that use up-follow, but are when called with up-target, provided up-target is not body.

I've looked through the code but it's not obvious where the issue might lie.

Thoughts?

(Unpoly 0.36.2, jQuery 2.2.4)

Appending content doesn't work if one of the targets is missing

Maybe more of a question than an issue…

Using [email protected] and the following Markup:

<div class="news-list">
  <!-- List of news Entries, each one is a <section> -->
</div>
<a href="news?start=3" 
   class="button button--load-more" 
   up-target=".news-list:after, .button--load-more">
  Load more
</a>

At the end of the list, the load-more button is omitted in the server generated output, eg. the last "page" of the news list looks like this:

<div class="news-list">
  <!-- Last news Entries, each one is a <section> -->
</div>
<!-- Load more button omitted -->

Appending new items works as long as the "load-more" button isn't omitted. If the button is missing, the "body" is completely replaced instead. Is there a way to set "soft" targets, so if they are missing from the response they get removed instead?

The workaround I'm currently using is returning something like this on the last page:

<div class="news-list">
  <!-- Last news Entries, each one is a <section> -->
</div>
<span class="button--load-more"></span>

Infinite Scroll Example/Tutorial

The design documentation mentions infinite scroll, however there isn't a clear example of it. It looks like the framework is capable of doing infinite scroll so It would be nice to have it in the tutorials.

Clarification / Example for docs

I was hoping that you could provide some clarification and possibly a dummy example of this line in the Modal Dialog docs.

"By default the dialog automatically closes when a link inside a modal changes a fragment behind the modal. This is useful to have the dialog interact with the page that opened it, e.g. by updating parts of a larger form."

Specifically I'm interested in the e.g. "By updated parts of a larger form".

I'm using a modal to bring up a form, of which I want the resulting save to update the form underneath the modal. Just a note, i'm using "up-target" on the form so that in the modal when there are validation errors it will display them inside the modal.

How can I update the underlying form the most idiomatic way?

Thanks!

Uncaught TypeError: Cannot read property 'offsetWidth' of null

I am having an odd interaction between unpoly and uikit. The version of uikit does not seem to matter, but something between 0.37.0 and 0.50.0 of unpoly.js is causing the following to be triggered.

This is happening during a call to up.extract()

What might have changed to cause this?

With some version combinations, things keep working, but I get the message. WIth others, it just stops working altogether. I'm thinking there is a race condition between handlers in uikit.js and unpoly.js, perhaps?

Any suggestions on where to look first? What kind of information could I supply to help narrow this down?

uikit.js:6682 Uncaught TypeError: Cannot read property 'offsetWidth' of null
    at UIkitComponent.write (uikit.js:6682)
    at uikit.js:2940
    at runTasks (uikit.js:1909)
    at Object.flush (uikit.js:1887)
write @ uikit.js:6682
(anonymous) @ uikit.js:2940
runTasks @ uikit.js:1909
flush @ uikit.js:1887
requestAnimationFrame (async)
scheduleFlush @ uikit.js:1902
read @ uikit.js:1870
(anonymous) @ uikit.js:2924
UIkit._callUpdate @ uikit.js:2913
update @ uikit.js:2814
UIkit.update @ uikit.js:2786
applyMutation @ uikit.js:2668
observe.childList @ uikit.js:2649
childList (async)
(anonymous) @ jquery.js:5930
domManip @ jquery.js:5743
after @ jquery.js:5928
jQuery.fn.(anonymous function) @ jquery.js:6036
detachWith @ unpoly.js:2020
transferKeepableElements @ unpoly.js:7121
swapElements @ unpoly.js:7079
(anonymous) @ unpoly.js:6981
group @ unpoly.js:4816
(anonymous) @ unpoly.js:6978
rejectOnError @ unpoly.js:2100
(anonymous) @ unpoly.js:6964
group @ unpoly.js:4816
extract @ unpoly.js:6954
applyPresto @ app.js:193
(anonymous) @ app.js:233
(anonymous) @ app.js:232
(anonymous) @ phoenix.js:619
trigger @ phoenix.js:618
(anonymous) @ phoenix.js:1042
(anonymous) @ phoenix.js:1041
decode @ phoenix.js:671
onConnMessage @ phoenix.js:1027
conn.onmessage @ phoenix.js:830

Body classes disappearing

Hello,

I've noticed that classes applied to body disappear when using an up-follow attribute on a link. I've confirmed they are in the response from the server during the request.

Looking through the code, it sounds like swapping actual body elements can be problematic, and my guess is coping the existing attributes from the old body element to new element is just as problematic.

Any thoughts?

(Up log attached)

machines 2017-03-14 12-25-00

invalid up-* html attributes

While i like most of the ideas behind unpoly i wondered why this library uses its invalid attribute handlers, resulting in around 300 validation Errors on its main page alone.

Is there a reason why it is based on invalid attributes instead of relying on valid data-* prefixed ones? At least it would be nice to maybe post process the resulting files by prefixing those attribute handlers (even if it means some effort for js files).

up-restore-scroll

We tried to update from 0.30.0 to 0.36.1.

After the update - when clicking an up-dash with up-restore-scroll="true" unpoly fails with the attached log.
The error occurs in restoreScroll().

The commit that introduced changed code to this function was: e673b2e#diff-c5eb160fb78f4fa757becb6f4a4ade82R435

 __ _____  ___  ___  / /_ __
/ // / _ \/ _ \/ _ \/ / // /  0.36.1
\___/_//_/ .__/\___/_/\_. / 
        / /            / /

Call `up.log.enable()` to enable logging for this session.
up.log.enable()
true
unpoly.js:2831 [UP] Preloading link jQuery.fn.init(1)
unpoly.js:2831 [UP] Re-using cached response for GET http://ypsilon.dev:4000/en/hwm/updates
unpoly.js:2831 [UP] Re-using cached response for GET http://ypsilon.dev:4000/en/hwm/updates
unpoly.js:2831 [UP] Extracting .js-publication_page_content from 10200 bytes of HTML
unpoly.js:2831 [UP] Saving scroll positions for URL http://ypsilon.dev:4000/en/hwm (Object)
unpoly.js:2831 [UP] Adding history entry for http://ypsilon.dev:4000/en/hwm/updates (up:history:push (Object))
unpoly.js:2831 [UP] Advanced to location http://ypsilon.dev:4000/en/hwm/updates (up:history:pushed (Object))
unpoly.js:2831 [UP] Updating .js-publication_page_content
unpoly.js:2831 [UP] Destroying fragment <div class=​"test-publication_landing_page js-
publication_page_content              up-destroying" style=​"display:​ none;​">​…​</div>​ (up:fragment:destroy)
unpoly.js:2831 [UP] Compiling fragment <div class=​"js-publication_page_content" up-source=​"http:​/​/​
ypsilon.dev:​4000/​en/​hwm/​updates">​…​</div>​
unpoly.js:2831 [UP] Compiling '.sticky' on 1 element(s)
unpoly.js:2831 [UP] Compiling '.sticky' on <div class=​"publication_funding_status__wrapper sticky
        publication_funding_status__wrapper--no_items">​…​</div>​
unpoly.js:2831 [UP] Inserted fragment <div class=​"js-publication_page_content" up-source=​"http:​/​/​
ypsilon.dev:​4000/​en/​hwm/​updates">​…​</div>​ (up:fragment:inserted (Object))
unpoly.js:2831 [UP] Restoring scroll positions for URL http://ypsilon.dev:4000/en/hwm/updates to undefined
unpoly.js:5264 Uncaught TypeError: Cannot read property 'document' of undefined
at HTMLDocument.<anonymous> (unpoly.js:5264)
at Function.each (jquery.js?27d9:365)
at jQuery.fn.init.each (jquery.js?27d9:137)
at unpoly.js:5260
at Object.group (unpoly.js:3775)
at restoreScroll (unpoly.js:5259)
at Object.revealOrRestoreScroll (unpoly.js:5283)
at skipMorph (unpoly.js:7117)
at unpoly.js:7096
at Object.group (unpoly.js:3782)

Update nearest target to origin

Hello,

I have the page with several sections and forms:

  <div class="section">
    <form up-target=".section"></form>
  </div>

  <div class="section">
    <form up-target=".section"></form>
  </div>

A form request returns one section only, not section list.
I've noticed, that when I submit the second form and get updated second list it will replace the first section on the page, and the old section remains unchanged.

What do you think about it?

X-Requested-With header missing

Frameworks like jQuery add a HTTP header X-Requested-With: XMLHttpRequest.
It is used to detect XHRs on the server side, for example in Rack.

Unpoly should maybe add this header by default. I understand that adding a non-standard header by default might be subject to heated discussions. 😉
Alternatively, we could allow configuring default headers like this via up.proxy.config or similar.

For the time being, I'll be using this workaround:

up.on('up:proxy:load', function(event) {
  event.request.headers['X-Requested-With'] = 'XMLHttpRequest';
})

Load javascript files along with template fragments

Is it possible to load page specific javascript files when I fetch a new page fragment ? For example:

I've page-a.html:

<html>
<head>
<script src="page-a.js"></script>
<body>
<a href="page-b.html" up-target=".page-content">Click here to load page B</a>
<div class="page-content">Content of page A</div>
</body>
</head>

And, there is page-b.html:

<html>
<head>
<script src="page-b.js"></script>
<body>
<a href="page-a.html" up-target=".page-content">Click here to load page A</a>
<div class="page-content">Content of page b</div>
</body>
</head>

When .page-content of page-b.html is inserted, I would lose page-b.js. How can I prevent this from happening ? Do I have to pre-load all scripts on all pages ?

missing 't' in 'matching'

Two times there's missing a 't' in 'matching' within "The functions will be called on elements maching [...]"

Unpoly documentation up-data invalid JSON

The unpoly documentation says something like this:

<div class="google-map" up-data="[
  { lat: 48.36, lng: 10.99, title: 'Friedberg' },
  { lat: 48.75, lng: 11.45, title: 'Ingolstadt' }
]"></div>

But isn't this an invalid JSON?

var test = [
  { lat: 48.36, lng: 10.99, title: 'Friedberg' },
  { lat: 48.75, lng: 11.45, title: 'Ingolstadt' }
]
JSON.parse(test)

Uncaught SyntaxError: Unexpected token o in JSON at position 1
    at JSON.parse (<anonymous>)
    at <anonymous>:1:6

For me something like this (different data) was working:

<div class="google-map" up-data='[
  { "lat": 48.36, "lng": 10.99, "title": "Friedberg" },
  { "lat": 48.75, "lng": 11.45, title: "Ingolstadt" }
]'></div>

Unpoly Links + Browser Back Button not triggering replace

using latest unpoly release [email protected]
and jquery 2.2.4

I have some up-target / up-dash links which correctly insert a history object into the browser's history stack when followed, but when i push the browser's back button (chrome) up:history:restored is never emitted

when i bind my own listener to window.popstate and inspect e.originalEvent.state is appears the state.fromUp flag property is missing

[UP] Ignoring a state not pushed by Unpoly

even when i explicitly set up-history attributes on the links

i'll work on putting together a reduced test case...

Updating <title> element and inline SVG icons

If the source of a requested site contains inline SVG with <title> elements, unpoly does not fetch the content of the <title> element in <head> but the one of the first inline SVG.

position: absolute and up-transition

Hi, when you have a page consisting of an non unpoly navbar and an body that is made with unpoly which has an animated page change.
Then absolute positioned (ie. top: 40%) elements will jump up and down during the page transition effect (move-left & move-right).

Greetings Lukas

Forms won't submit when form ID contains a slash

Unpoly will not submit <form> tags with an id attribute that contains a slash.

The request is never made, and there is no error message in the browser console.
Enabling Unpoly logging also does not print any information.

Examples:

I'd expect Unpoly to behave as it would without any slashes inside the ID.
If that is not possible, an error should be thrown.

Non-200 Error Handling Question

During development, replacing the whole body with any and all server errors is great.
For production, not so great.

Is there a way I could prevent the entire body from being replaced on a failed up.replace call?

So that I may print a simpler, user-friendly error message about the server error? instead of printing exactly what the XHR returned and blowing away the user's entire context / state?

I tried setting the failLayer to auto, page, popup and modal, so that i could just sweep the error under the rug so-to-speak, to give the user a chance to navigate away to something else...

but they all fail with:

[UP] Could not find failure target in current popup (tried ["body"])
--
[UP] Could not find failure target in current modal (tried ["body"])
--
[UP] Could not find failure target in response (tried [".overlay-error-container"])

which breaks JS execution beyond that point, so my .fail handler never gets a chance to display my simplified error message.

localstorage values disappear on link follow

i have form vars stored in localstorage ie address:xxxxxxx
when i follow a link like
var $link = $('#start_quote');
up.follow($link);
all that is left is the keys the values are nulled

Using both up-hide-for and up-show-for for the same element with up-switch

I had an issue where up-hide-for and up-show-for behaves different on those two actions:

<select name="advancedness" up-switch=".target">
  <option value="basic">Basic parts</option>
  <option value="advanced">Advanced parts</option>
  <option value="very-advanced">Very advanced parts</option>
</select>
<div class="target" up-show-for="advanced very-advanced" up-hide-for="basic">
  Some example
</div>
  1. When switching between basic and advanced the target shows and hides correctly.
  2. When loading a page, where advanced is already selected, the target was not shown, even it should be.

The fix was to simply use show-for and remove hide-for (it clearly makes no sense to use both).

Do you think it makes sense to highlight this in the documentation, that not both can be used? Or maybe output some warning on the console. I'm also okey with just closing this issue.

up-transition speed example

Hi!

Thanks for this great framework. It is very easy to use and extremely functional!

As a beginner in JS, I would like to know if you could provide an example for setting the speed/duration of a predefined up-transition (I am using "move-up").
Also, it would be amazing if you could give us more example for integrating JS custom scripts. It seems that the up.compiler function needs a selector. I might be wrong, but some custom scripts do not always use a selector, no?

Hope I am not asking too much!

All the best,
MB

Documentation lacks examples

Modals, tooltips, etc lack examples. As a potential user I'd like to see how they work.

For example, when I select "Modal dialogs" from sidebar, I expect there to be some example.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.