Re: ajax onBlur callback with load html: [...]

"[email protected]" <[email protected]> Thu, 16 Sep 2021 20:04:13 +0200
Newsgroups gmane.comp.lang.smalltalk.squeak.seaside
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============0976940869649839585==
Content-Type: multipart/alternative;
 boundary="------------E46FF8329688FEAB6BC7948B"
Content-Language: de-DE

This is a multi-part message in MIME format.
--------------E46FF8329688FEAB6BC7948B
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit

Hi Bob,

it takes quite some courage to answer after Johan's excessive post ;-)
I try anyways, because there is one thing in the back og my mind that 
seems related, even if it may not be the ultimate solution.

sending onClick: to a button registers an event handler with the button. 
So far, so good. If you replace this button with another button, it is 
logical that the event handler also goes away and is not registered with 
the new button any more.

We've had similar problems with elements that are not rendered on the 
page at render time (part of the response that initially rendered the 
page). So we had to register an event handler with the doument using an 
extra selector. in Javascript you'd have to do it like this:

$(document).on("click","button#idOfTheButton", function(event) {...} );  
(see https://api.jquery.com/on/ <https://api.jquery.com/on/> for details)

In Seaside, this would look like this:


     (html jQuery document)
                 on: 'blur'
                 selector: '#myButton'
                 do: (
                     (html jQuery ajax) ....


The effect of this is that $(document) is always there and will check 
each click event whether it was triggered by an element which matches 
"button#idOfTheButton". This means, replacing a button with another one 
that matches the selector will still be triggered.


As I said, I am not 100% sure this is what you are looking for, but it 
might be worth looking at.


HTH

Joachim






Am 16.09.21 um 10:30 schrieb Johan Brichau:
> Hi Bob,
>
> The JQAjax#callback being nil is normal if there is no “primary” 
> callback. This is what you see: the Ajax callback registered on the 
> onblur event (using JQAjax>>callback:value:, which is a secondary 
> callback) has no primary callback block. The Ajax callback registered 
> on the onClick event only has a primary callback block. This is fine 
> and works as intended.
>
> The problem you are seeing is on the client side and all about browser 
> events: the click on the button triggers the browser’s onBlur event 
> first, which triggers the Seaside callback for the blur, which 
> triggers another callback to replace the html snippet including the 
> button you pressed and the input field that triggered the blur. The 
> html load replaces the button you are clicking….  Now, depending on 
> the speed of events and callbacks, the html (including your button) 
> will be replaced before or after the browser can send the onClick 
> event to the button, which would trigger the Seaside callback for the 
> button.
>
> In addition, there is the ordering of events in the browser that makes 
> this very complicated to think about: an onClick is only fired after a 
> mouseDown and a mouseUp and an onBlur is sent because of the mouseDown 
> on the button.
>
> If you include a 100ms delay in the response of the Seaside callback, 
> you are effectively making it possible for the browser to trigger the 
> onClick event on the original button as well.
> Without this delay, the browser will have sent the mouseDown event to 
> the button but the button will be replaced before the browser is able 
> to trigger a mouseUp and an onClick.
> Because the new button is not the one you clicked, it will not have 
> it’s onclick handler fired.
>
> If you do not replace the button while rendering the Ajax update, it 
> works as well.
>
> Doing some console logging can be helpful to debug such issues. See 
> code below and try with or without the delay commented out.
>
> html textInput
> value: self stringValue;
> onBlur: ((JSStream on: 'console.log(''onblur'')'),
> (html jQuery ajax callback: [:value |
> self stringValue: value. (Delay forMilliseconds: 100) wait.
> Transcript cr; show: Time now displayString  , ' value: ' , value 
> asString]
> value: (html jQuery this value);
> onSuccess: ((JSStream on: 'console.log(''contentload-onblur'')'),(self 
> renderContentLoadDivOn: html) ))).
> html break; break.
> html button
> onClick: ( (JSStream on: 'console.log(''onclick'')'),
> (html jQuery ajax callback: [
> self stringValue: self stringValue , '+'.
> Transcript cr; show: Time now displayString , ' button: ' , self 
> stringValue asString];
> onSuccess: ((JSStream on: 
> 'console.log(''contentload-onclick'')'),(self renderContentLoadDivOn: 
> html) )));
> with: 'Press’.
>
>
> Hope this helps,
> Johan
>
>> On 15 Sep 2021, at 23:40, Bob Nemec <[email protected] 
>> <mailto:[email protected]>> wrote:
>>
>>
>> Wow, this is proving to be challenge. The problem is that in 
>> JQAjax>>processCallback #callback is sometimes nil. When it is, the 
>> button press callback is not processed and the button has to be 
>> pressed again. But, if the onBlur of the text input field has a 100ms 
>> delay, the #callback value is not nil and the button callback works 
>> all the time. Which is especially frustrating because adding 
>> diagnostic traces slows down the first callback enough for things to 
>> work.
>>
>> This is pushing me to the edge of my Seaside knowledge. I will try 
>> this same example with the latest Seaside code on Pharo. If it works, 
>> I'll work on getting us updated (we develop in VW but deploy on GS). 
>> If not, I'll have a nice packaged problem to raise on the Seaside 
>> part of the Pharo Discord channel.
>>
>> Bob
>>
>> On Tuesday, September 14, 2021, 08:58:31 a.m. EDT, Karsten Kusche 
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>>
>> Hi Bob,
>>
>>> We use onBlur to get the data from input fields and to refresh the 
>>> state of the view. The problem comes up if a button is included in 
>>> the refresh: the ajax callback from that button is not handled 
>>> (which makes sense due to the jQuery load), so the user has to press 
>>> the button again.
>>
>> I’d say it actually doesn’t make any sense. Your callbacks are 
>> registered, they should work regardless. You could use the 
>> Web-Browser’s network tool/profiler to see which event-handler is 
>> fired and what network requests are made. Maybe one of the requests 
>> doesn’t come through correctly and you can investigate that further.
>>
>> Some things you should also consider: when you use render 
>> HTML-Snippets that contain Javascript (like new click-handlers), 
>> Seaside will automatically add these inside a <script>-tag at the end 
>> of this snippet and inject that into your DOM at the place where you 
>> inject the HTML. In your case you should have a <script>-tag at the 
>> end of your #testDiv.
>>
>> I’m not entirely sure about this, but iirc replacing that script-tag 
>> will also remove all event-handlers that were registered as part of 
>> this tag. On the other hand replacing the <script> also means 
>> replacing the <button> so you should still have a working button in 
>> any case… like i said, it doesn’t really make much sense.
>>
>> Karsten
>>
>> _______________________________________________
>> seaside mailing list
>> [email protected] 
>> <mailto:[email protected]>
>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside 
>> <http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside>
>
>
> _______________________________________________
> seaside mailing list
> [email protected]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside


-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          mailto:[email protected]
Fliederweg 1                         http://www.objektfabrik.de
D-71640 Ludwigsburg                  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1



--------------E46FF8329688FEAB6BC7948B
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">Hi Bob, <br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">it takes quite some courage to answer
      after Johan's excessive post ;-) <br>
    </div>
    <div class="moz-cite-prefix">I try anyways, because there is one
      thing in the back og my mind that seems related, even if it may
      not be the ultimate solution.</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">sending onClick: to a button registers
      an event handler with the button. So far, so good. If you replace
      this button with another button, it is logical that the event
      handler also goes away and is not registered with the new button
      any more. <br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">We've had similar problems with
      elements that are not rendered on the page at render time (part of
      the response that initially rendered the page). So we had to
      register an event handler with the doument using an extra
      selector. in Javascript you'd have to do it like this:<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">$(document).on("click","button#idOfTheButton",
      function(event) {...} );  (see <a moz-do-not-send="true"
        href="https://api.jquery.com/on/">https://api.jquery.com/on/</a>
      for details)<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <p>In Seaside, this would look like this:</p>
    <p><br>
    </p>
    <p>    (html jQuery document)<br>
                      on: 'blur'<br>
                      selector: '#myButton'<br>
                      do: (<br>
                          (html jQuery ajax) ....<br>
    </p>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">The effect of this is that $(document)
      is always there and will check each click event whether it was
      triggered by an element which matches "button#idOfTheButton". This
      means, replacing a button with another one that matches the
      selector will still be triggered.</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">As I said, I am not 100% sure this is
      what you are looking for, but it might be worth looking at.</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">HTH</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Joachim<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Am 16.09.21 um 10:30 schrieb Johan
      Brichau:<br>
    </div>
    <blockquote type="cite"
      cite="mid:[email protected]">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      Hi Bob,
      <div class=""><br class="">
      </div>
      <div class="">The JQAjax#callback being nil is normal if there is
        no “primary” callback. This is what you see: the Ajax callback
        registered on the onblur event (using
        JQAjax&gt;&gt;callback:value:, which is a secondary callback)
        has no primary callback block. The Ajax callback registered on
        the onClick event only has a primary callback block. This is
        fine and works as intended.</div>
      <div class=""><br class="">
      </div>
      <div class="">The problem you are seeing is on the client side and
        all about browser events: the click on the button triggers the
        browser’s onBlur event first, which triggers the Seaside
        callback for the blur, which triggers another callback to
        replace the html snippet including the button you pressed and
        the input field that triggered the blur. The html load replaces
        the button you are clicking….  Now, depending on the speed of
        events and callbacks, the html (including your button) will be
        replaced before or after the browser can send the onClick event
        to the button, which would trigger the Seaside callback for the
        button. </div>
      <div class=""><br class="">
      </div>
      <div class="">In addition, there is the ordering of events in the
        browser that makes this very complicated to think about: an
        onClick is only fired after a mouseDown and a mouseUp and an
        onBlur is sent because of the mouseDown on the button.</div>
      <div class=""><br class="">
      </div>
      <div class="">If you include a 100ms delay in the response of the
        Seaside callback, you are effectively making it possible for the
        browser to trigger the onClick event on the original button as
        well.</div>
      <div class="">Without this delay, the browser will have sent the
        mouseDown event to the button but the button will be replaced
        before the browser is able to trigger a mouseUp and an onClick. </div>
      <div class="">Because the new button is not the one you clicked,
        it will not have it’s onclick handler fired.</div>
      <div class=""><br class="">
      </div>
      <div class="">If you do not replace the button while rendering the
        Ajax update, it works as well.</div>
      <div class=""><br class="">
      </div>
      <div class="">
        <div>Doing some console logging can be helpful to debug such
          issues. See code below and try with or without the delay
          commented out.</div>
        <div><br class="">
        </div>
        <div>
          <div><span class="Apple-tab-span" style="white-space:pre">	</span>html
            textInput </div>
          <div><span class="Apple-tab-span" style="white-space:pre">		</span>value:
            self stringValue; </div>
          <div><span class="Apple-tab-span" style="white-space:pre">		</span>onBlur:
            ((JSStream on: 'console.log(''onblur'')'),</div>
          <div><span class="Apple-tab-span" style="white-space:pre">				</span>(html
            jQuery ajax callback: [:value | </div>
          <div><span class="Apple-tab-span" style="white-space:pre">						</span>self
            stringValue: value. (Delay forMilliseconds: 100) wait.</div>
          <div><span class="Apple-tab-span" style="white-space:pre">						</span>Transcript
            cr; show: Time now displayString  , ' value: ' , value
            asString]</div>
          <div><span class="Apple-tab-span" style="white-space:pre">				</span>value:
            (html jQuery this value); </div>
          <div><span class="Apple-tab-span" style="white-space:pre">			</span>onSuccess:
            ((JSStream on: 'console.log(''contentload-onblur'')'),(self
            renderContentLoadDivOn: html) ))).</div>
          <div><span class="Apple-tab-span" style="white-space:pre">	</span>html
            break; break. </div>
          <div><span class="Apple-tab-span" style="white-space:pre">	</span>html
            button </div>
          <div><span class="Apple-tab-span" style="white-space:pre">		</span>onClick:
            ( (JSStream on: 'console.log(''onclick'')'),</div>
          <div><span class="Apple-tab-span" style="white-space:pre">				</span>(html
            jQuery ajax callback: [</div>
          <div><span class="Apple-tab-span" style="white-space:pre">					</span>self
            stringValue: self stringValue , '+'.</div>
          <div><span class="Apple-tab-span" style="white-space:pre">					</span>Transcript
            cr; show: Time now displayString , ' button: ' , self
            stringValue asString];</div>
          <div><span class="Apple-tab-span" style="white-space:pre">			</span>onSuccess:
            ((JSStream on: 'console.log(''contentload-onclick'')'),(self
            renderContentLoadDivOn: html) )));</div>
          <div><span class="Apple-tab-span" style="white-space:pre">		</span>with:
            'Press’.</div>
          <div><br class="">
          </div>
          <div><br class="">
          </div>
          <div>Hope this helps,</div>
          <div>Johan</div>
          <div><br class="">
          </div>
          <blockquote type="cite" class="">
            <div class="">On 15 Sep 2021, at 23:40, Bob Nemec &lt;<a
                href="mailto:[email protected]" class=""
                moz-do-not-send="true">[email protected]</a>&gt; wrote:</div>
            <br class="Apple-interchange-newline">
            <div class="">
              <div class="ydpb0c0ebbayahoo-style-wrap"
                style="caret-color: rgb(0, 0, 0); font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none; font-family: &quot;lucida
                console&quot;, sans-serif; font-size: 13px;">
                <div dir="ltr" data-setdir="false" class=""><br
                    class="Apple-interchange-newline">
                  Wow, this is proving to be challenge. The problem is
                  that in <span class="">JQAjax&gt;&gt;processCallback #<span
                      class="">callback is sometimes nil. When it is,
                      the button press callback is not processed and the
                      button has to be pressed again. But, if the onBlur
                      of the text input field has a 100ms delay, the
                      #callback value is not nil and the button callback
                      works all the time. Which is especially
                      frustrating because adding diagnostic traces slows
                      down the first callback enough for things to
                      work. </span></span></div>
                <div dir="ltr" data-setdir="false" class=""><span
                    class=""><span class=""><br class="">
                    </span></span></div>
                <div dir="ltr" data-setdir="false" class=""><span
                    class=""><span class="">This is pushing me to the
                      edge of my Seaside knowledge. I will try this same
                      example with the latest Seaside code on Pharo. If
                      it works, I'll work on getting us updated (we
                      develop in VW but deploy on GS). If not, I'll have
                      a nice packaged problem to raise on the Seaside
                      part of the Pharo Discord channel. </span></span></div>
                <div dir="ltr" data-setdir="false" class=""><span
                    class=""><span class=""><br class="">
                    </span></span></div>
                <div dir="ltr" data-setdir="false" class=""><span
                    class=""><span class="">Bob</span></span></div>
                <div dir="ltr" data-setdir="false" class=""><span
                    class=""><span class=""><br class="">
                    </span></span></div>
              </div>
              <div id="yahoo_quoted_2112089454" class="yahoo_quoted"
                style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none;">
                <div style="font-family: &quot;Helvetica Neue&quot;,
                  Helvetica, Arial, sans-serif; font-size: 13px; color:
                  rgb(38, 40, 42);" class="">
                  <div class="">On Tuesday, September 14, 2021, 08:58:31
                    a.m. EDT, Karsten Kusche &lt;<a
                      href="mailto:[email protected]" class=""
                      moz-do-not-send="true">[email protected]</a>&gt;
                    wrote:</div>
                  <div class=""><br class="">
                  </div>
                  <div class=""><br class="">
                  </div>
                  <div class="">
                    <div id="yiv0857676699" class="">
                      <div class="">
                        <div style="font-family: Helvetica, Arial;
                          font-size: 13px;" class="">Hi Bob,</div>
                        <div class="yiv0857676699yqt6264543426"
                          id="yiv0857676699yqtfd02179">
                          <div style="font-family: Helvetica, Arial;
                            font-size: 13px;" class=""><br class=""
                              clear="none">
                          </div>
                        </div>
                        <div class="">
                          <blockquote class="yiv0857676699clean_bq"
                            type="cite" style="font-family: Helvetica,
                            Arial; font-size: 13px; font-style: normal;
                            font-weight: normal; letter-spacing: normal;
                            text-indent: 0px; text-transform: none;
                            white-space: normal; word-spacing: 0px;
                            text-decoration: none;">
                            <div class="yiv0857676699yqt6264543426"
                              id="yiv0857676699yqtfd95783"><span
                                class=""></span>
                              <div class="">We use onBlur to get the
                                data from input fields and to refresh
                                the state of the view. The problem comes
                                up if a button is included in the
                                refresh: the ajax callback from that
                                button is not handled (which makes sense
                                due to the jQuery load), so the user has
                                to press the button again.</div>
                            </div>
                          </blockquote>
                        </div>
                        <p class="">I’d say it actually doesn’t make any
                          sense. Your callbacks are registered, they
                          should work regardless. You could use the
                          Web-Browser’s network tool/profiler to see
                          which event-handler is fired and what network
                          requests are made. Maybe one of the requests
                          doesn’t come through correctly and you can
                          investigate that further. </p>
                        <p class="">Some things you should also
                          consider: when you use render HTML-Snippets
                          that contain Javascript (like new
                          click-handlers), Seaside will automatically
                          add these inside a &lt;script&gt;-tag at the
                          end of this snippet and inject that into your
                          DOM at the place where you inject the HTML. In
                          your case you should have a &lt;script&gt;-tag
                          at the end of your #testDiv. </p>
                        <p class="">I’m not entirely sure about this,
                          but iirc replacing that script-tag will also
                          remove all event-handlers that were registered
                          as part of this tag. On the other hand
                          replacing the &lt;script&gt; also means
                          replacing the &lt;button&gt; so you should
                          still have a working button in any case… like
                          i said, it doesn’t really make much sense.</p>
                        <p class="">Karsten</p>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <span style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none; float: none; display: inline
                !important;" class="">_______________________________________________</span><br
                style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none;" class="">
              <span style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none; float: none; display: inline
                !important;" class="">seaside mailing list</span><br
                style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none;" class="">
              <span style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none; float: none; display: inline
                !important;" class=""><a
                  href="mailto:[email protected]"
                  class="" moz-do-not-send="true">[email protected]</a></span><br
                style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none;" class="">
              <span style="caret-color: rgb(0, 0, 0); font-family:
                Helvetica; font-size: 12px; font-style: normal;
                font-variant-caps: normal; font-weight: normal;
                letter-spacing: normal; text-align: start; text-indent:
                0px; text-transform: none; white-space: normal;
                word-spacing: 0px; -webkit-text-stroke-width: 0px;
                text-decoration: none; float: none; display: inline
                !important;" class=""><a
href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside"
                  class="" moz-do-not-send="true">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a></span></div>
          </blockquote>
        </div>
        <br class="">
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
seaside mailing list
<a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
<a class="moz-txt-link-freetext" href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside</a>
</pre>
    </blockquote>
    <p><br>
    </p>
    <pre class="moz-signature" cols="72">-- 
-----------------------------------------------------------------------
Objektfabrik Joachim Tuchel          <a class="moz-txt-link-freetext" href="mailto:[email protected]">mailto:[email protected]</a>
Fliederweg 1                         <a class="moz-txt-link-freetext" href="http://www.objektfabrik.de">http://www.objektfabrik.de</a>
D-71640 Ludwigsburg                  <a class="moz-txt-link-freetext" href="http://joachimtuchel.wordpress.com">http://joachimtuchel.wordpress.com</a>
Telefon: +49 7141 56 10 86 0         Fax: +49 7141 56 10 86 1


</pre>
  </body>
</html>

--------------E46FF8329688FEAB6BC7948B--

--===============0976940869649839585==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18Kc2Vhc2lkZSBt
YWlsaW5nIGxpc3QKc2Vhc2lkZUBsaXN0cy5zcXVlYWtmb3VuZGF0aW9uLm9yZwpodHRwOi8vbGlz
dHMuc3F1ZWFrZm91bmRhdGlvbi5vcmcvY2dpLWJpbi9tYWlsbWFuL2xpc3RpbmZvL3NlYXNpZGUK

--===============0976940869649839585==--